mirror of
https://github.com/apache/struts.git
synced 2026-08-09 16:46:55 +00:00
Compare commits
202 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e903739624 | |||
| a85328e74e | |||
| c3deb39237 | |||
| 483a0c8d01 | |||
| f5c0aa5f3a | |||
| a77a80a803 | |||
| 4d58dd1960 | |||
| 09da11ba06 | |||
| bcfa8113ac | |||
| 65ae2b7e4f | |||
| 1af3e31548 | |||
| 18a72c3dff | |||
| 6ea50122d6 | |||
| ea7fba2846 | |||
| 4ab427f2f2 | |||
| 0a30eb44e6 | |||
| 138a8d74f0 | |||
| 341a8f20e0 | |||
| 9a431ea470 | |||
| 0fe27a673d | |||
| 35a50ea836 | |||
| 927c58b7d3 | |||
| ac168968a0 | |||
| 5a30cdbede | |||
| bfcc0b5898 | |||
| 4a51aacf40 | |||
| 728edbef56 | |||
| 6135a71335 | |||
| 6330bb1ce3 | |||
| 4a585347ed | |||
| 4bb81d5909 | |||
| 054f1f4cdb | |||
| 79a84a8f02 | |||
| 2660aaec56 | |||
| 34aeeded55 | |||
| 8d2d996056 | |||
| 6658c6360e | |||
| 9c078aef14 | |||
| eb51594ed3 | |||
| b536136191 | |||
| c74287f741 | |||
| 9e7e0b395d | |||
| 784293e46f | |||
| 58dcc830ea | |||
| 936481e7ea | |||
| a02cc6507c | |||
| 084c257d6e | |||
| 94a0c6e425 | |||
| 3e30d0c375 | |||
| 9568888700 | |||
| 943cb62953 | |||
| 79d6c07a57 | |||
| 7064c53f5c | |||
| 3fdb918127 | |||
| 1069cf8c09 | |||
| c41f05fe68 | |||
| 993c4c4cab | |||
| 01164c4d74 | |||
| 738d27952f | |||
| 984f8eff2e | |||
| 802afb0cc0 | |||
| 339c30320a | |||
| a562f8f806 | |||
| ac13c32bdb | |||
| bb71610296 | |||
| 3d7f66f428 | |||
| 50842e8d19 | |||
| cca986df35 | |||
| 511ec62105 | |||
| 2cb0d28960 | |||
| e783d18715 | |||
| 864f513365 | |||
| 9dd2560172 | |||
| 415e0fbd44 | |||
| 26effbf05d | |||
| 4c8cc361d5 | |||
| a21bd994eb | |||
| 8f0db1d22a | |||
| 58f287bf4a | |||
| e0da03c262 | |||
| 04cf1dae5f | |||
| 5338b44c23 | |||
| 2217e2c1ca | |||
| cbfd3a7ab9 | |||
| 097297affd | |||
| ddfaa1683c | |||
| ddbd02e6bb | |||
| 6887ef900b | |||
| 326de812ac | |||
| 32201b2ef2 | |||
| a4fe51f5b3 | |||
| 3774ffa7c3 | |||
| cf2078d1de | |||
| 7183d32caf | |||
| e0e7e3cb20 | |||
| eb68368280 | |||
| 296b3cc89c | |||
| 9fb86054bb | |||
| 0fc71949ca | |||
| 9faa002fa7 | |||
| 88bc5c6802 | |||
| dc1a663d69 | |||
| 36ac23acf5 | |||
| 6b2cc20b2d | |||
| ab22c7377d | |||
| 062b76718b | |||
| dc5dac7be2 | |||
| 6334a3e19e | |||
| 858f19557d | |||
| d97fa1eb38 | |||
| b9cd7d8159 | |||
| 03edeee0d8 | |||
| f04b68db03 | |||
| 7b655207ec | |||
| c9c39130f6 | |||
| 12beb20949 | |||
| a5899726a0 | |||
| 22a80f9c51 | |||
| 854572905e | |||
| b40f3efc74 | |||
| 980387e91c | |||
| 5a3d2c4eb9 | |||
| 8514406142 | |||
| bbb5b6bb37 | |||
| ce2975e2f0 | |||
| 49240c50a2 | |||
| 941d88d115 | |||
| 8c4a90f6e3 | |||
| 16c2948f1a | |||
| 58a76162a6 | |||
| b5e802174a | |||
| cdb70e6bed | |||
| 1380802b75 | |||
| 253d8558e5 | |||
| a97ee9e9cb | |||
| 23969abc19 | |||
| 2707bf0489 | |||
| 74d4e23716 | |||
| 2a03047e9e | |||
| b1c1be6e40 | |||
| 6536dc65d8 | |||
| 915386816b | |||
| 80c2de9e92 | |||
| b62e583646 | |||
| 8b359383a1 | |||
| 11e716f979 | |||
| 71c7064f29 | |||
| 09472808aa | |||
| d119ba8e13 | |||
| 86b45e96fc | |||
| 3c9465b857 | |||
| 0c73cf2e05 | |||
| 6785997412 | |||
| 5a7fce066f | |||
| 4fbada4cd9 | |||
| 15bbf0ef1d | |||
| 3119eb65db | |||
| de3dabbe44 | |||
| 82f7904206 | |||
| 42e3da550f | |||
| f3cb89202d | |||
| 836a27692e | |||
| 6312572331 | |||
| e7db7ade62 | |||
| b77c2f476a | |||
| e6c1cec7f8 | |||
| a781b5a27b | |||
| b71732fa14 | |||
| 3f79d64e6a | |||
| 039fd9f4ee | |||
| 393d5be50c | |||
| 24e279b165 | |||
| cb59974903 | |||
| ecfdee137d | |||
| 8c37b1523f | |||
| 62b83021a2 | |||
| f3f2d52a1c | |||
| 61ded9a3e7 | |||
| 963b473e6c | |||
| d639b59f6d | |||
| 8e468a368e | |||
| ebe1b80ed2 | |||
| 957292ecdb | |||
| 06290cef91 | |||
| a6a4529503 | |||
| 64d054221f | |||
| dc4e403d30 | |||
| e6bc93daf2 | |||
| 0e4d5962e1 | |||
| 69102e9075 | |||
| 1c2b491a27 | |||
| 5af840b160 | |||
| b6b74a46ea | |||
| fc2aebd10a | |||
| ba041e1ee6 | |||
| 0c3534e8b4 | |||
| 9a2996f9b7 | |||
| 3825229f44 | |||
| 584634a9b5 | |||
| 5763476830 | |||
| 105b22fb9a | |||
| 4b3ee53f93 |
@@ -12,3 +12,5 @@ notifications:
|
||||
|
||||
github:
|
||||
del_branch_on_merge: true
|
||||
protected_branches:
|
||||
master: { }
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
# 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.
|
||||
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'java' ]
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
||||
@@ -0,0 +1,57 @@
|
||||
# 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.
|
||||
|
||||
name: Java Build
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
env:
|
||||
MAVEN_OPTS: -Xmx2048m -Xms1024m
|
||||
LANG: en_US.utf8
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
java: [ '8', '11', '17' ]
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3.0.2
|
||||
- name: Set up cache
|
||||
uses: actions/cache@v3.0.8
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-maven-
|
||||
- name: Set up JDK ${{ matrix.java }}
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: adopt
|
||||
java-version: ${{ matrix.java }}
|
||||
- name: Build with Maven on Java ${{ matrix.java }}
|
||||
if: matrix.java != '11'
|
||||
run: mvn -B -V -DskipAssembly test --no-transfer-progress
|
||||
- name: Code coverage on Java ${{ matrix.java }}
|
||||
if: matrix.java == '11'
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SONAR_TOKEN: ${{ secrets.SONARCLOUD_TOKEN }}
|
||||
run: mvn -B -V -Pcoverage -DskipAssembly verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar --no-transfer-progress
|
||||
@@ -0,0 +1,69 @@
|
||||
# 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.
|
||||
|
||||
name: "Scorecards supply-chain security"
|
||||
|
||||
on:
|
||||
branch_protection_rule:
|
||||
schedule:
|
||||
- cron: "30 1 * * 6" # Weekly on Saturdays
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
|
||||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
|
||||
analysis:
|
||||
|
||||
name: "Scorecards analysis"
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
# Needed to upload the results to the code-scanning dashboard.
|
||||
security-events: write
|
||||
actions: read
|
||||
id-token: write # This is required for requesting the JWT
|
||||
contents: read # This is required for actions/checkout
|
||||
|
||||
steps:
|
||||
|
||||
- name: "Checkout code"
|
||||
uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # 3.1.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: "Run analysis"
|
||||
uses: ossf/scorecard-action@99c53751e09b9529366343771cc321ec74e9bd3d # 2.0.6
|
||||
with:
|
||||
results_file: results.sarif
|
||||
results_format: sarif
|
||||
# A read-only PAT token, which is sufficient for the action to function.
|
||||
# The relevant discussion: https://github.com/ossf/scorecard-action/issues/188
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# Publish the results for public repositories to enable scorecard badges.
|
||||
# For more details: https://github.com/ossf/scorecard-action#publishing-results
|
||||
publish_results: true
|
||||
|
||||
- name: "Upload artifact"
|
||||
uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # 3.1.0
|
||||
with:
|
||||
name: SARIF file
|
||||
path: results.sarif
|
||||
retention-days: 5
|
||||
|
||||
- name: "Upload to code-scanning"
|
||||
uses: github/codeql-action/upload-sarif@b398f525a5587552e573b247ac661067fafa920b # 2.1.22
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
+1
-1
@@ -14,5 +14,5 @@
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.5/apache-maven-3.8.5-bin.zip
|
||||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.6/apache-maven-3.8.6-bin.zip
|
||||
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar
|
||||
|
||||
-29
@@ -1,29 +0,0 @@
|
||||
dist: trusty
|
||||
language: java
|
||||
sudo: false
|
||||
|
||||
jdk:
|
||||
- oraclejdk9
|
||||
- oraclejdk11
|
||||
|
||||
install: true
|
||||
|
||||
env:
|
||||
global:
|
||||
- secure: iI7IpfDtS+LUyS2yNuRCR3KelNyvBHuoMQ3gb1UNmR5SSL7jO/p3olQWrQROs28FJ+dpE3lHyIjoHrebKQGJHHAgTG2XWxn+G3fDsf+wSSFSLoDGj0o2SgGXooBbR2dccnNZHCyQaOyE2cIPWaOxrQZFE4No70LQB4mrP/gdkoc=
|
||||
matrix:
|
||||
include:
|
||||
- jdk: oraclejdk8
|
||||
env: STRUTS_IT=true # do integration tests and coverage reports when jdk 9 and 11 tests prospered
|
||||
|
||||
script:
|
||||
- if [ "$STRUTS_IT" == "true" ]; then
|
||||
./mvnw clean install -DskipTests -DskipAssembly -B;
|
||||
./mvnw test org.jacoco:jacoco-maven-plugin:report org.jacoco:jacoco-maven-plugin:report-integration org.eluder.coveralls:coveralls-maven-plugin:report -Ptravis-coveralls -DskipAssembly -B;
|
||||
else
|
||||
./mvnw clean package test -DskipAssembly -B;
|
||||
fi;
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.m2
|
||||
Vendored
+5
-3
@@ -79,7 +79,7 @@ pipeline {
|
||||
}
|
||||
stage('Test') {
|
||||
steps {
|
||||
sh './mvnw -B test'
|
||||
sh './mvnw -B verify -Pcoverage -DskipAssembly'
|
||||
}
|
||||
post {
|
||||
always {
|
||||
@@ -94,7 +94,7 @@ pipeline {
|
||||
}
|
||||
steps {
|
||||
withCredentials([string(credentialsId: 'asf-struts-sonarcloud', variable: 'SONARCLOUD_TOKEN')]) {
|
||||
sh './mvnw sonar:sonar -DskipAssembly -Dsonar.login=${SONARCLOUD_TOKEN}'
|
||||
sh './mvnw -B -Pcoverage -DskipAssembly -Dsonar.login=${SONARCLOUD_TOKEN} verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar'
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -160,6 +160,7 @@ pipeline {
|
||||
branch 'master'
|
||||
}
|
||||
steps {
|
||||
sh './mvnw -B package -DskipTests'
|
||||
sshPublisher(publishers: [
|
||||
sshPublisherDesc(
|
||||
configName: 'Nightlies',
|
||||
@@ -167,7 +168,8 @@ pipeline {
|
||||
sshTransfer(
|
||||
remoteDirectory: '/struts/snapshot',
|
||||
removePrefix: 'assembly/target/assembly/out',
|
||||
sourceFiles: 'assembly/target/assembly/out/struts-*.zip'
|
||||
sourceFiles: 'assembly/target/assembly/out/struts-*.zip',
|
||||
cleanRemote: true
|
||||
)
|
||||
],
|
||||
verbose: true
|
||||
|
||||
@@ -17,11 +17,13 @@
|
||||
The Apache Struts web framework
|
||||
-------------------------------
|
||||
|
||||
[](https://ci-builds.apache.org/job/Struts/job/Struts%20Core/job/master/)
|
||||
[](https://app.travis-ci.com/apache/struts)
|
||||
[](https://ci-builds.apache.org/job/Struts/job/Struts%20Core/job/master/)
|
||||
[](https://github.com/apache/struts/actions/workflows/maven.yml)
|
||||
[](https://maven-badges.herokuapp.com/maven-central/org.apache.struts/struts2-core/)
|
||||
[](https://javadoc.io/doc/org.apache.struts/struts2-core)
|
||||
[](https://coveralls.io/github/apache/struts)
|
||||
[](https://sonarcloud.io/summary/new_code?id=apache_struts)
|
||||
[](https://deps.dev/maven/org.apache.struts%3Astruts2-core)
|
||||
[](https://bestpractices.coreinfrastructure.org/projects/6618)
|
||||
[](http://www.apache.org/licenses/LICENSE-2.0.html)
|
||||
|
||||
The Apache Struts web framework is a free open-source solution for creating Java web applications.
|
||||
|
||||
+2
-2
@@ -7,8 +7,8 @@ and what potential vulnerability it can have:
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| 2.5.20 | :white_check_mark: |
|
||||
| 2.3.37 | :white_check_mark: |
|
||||
| 6.0.0 | :white_check_mark: |
|
||||
| 2.5.30 | :white_check_mark: |
|
||||
|
||||
## Reporting New Security Issues with thr Apache Struts
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
# Struts 2 Apps
|
||||
These module consists of two example applications, which were built using the Apache Struts project.
|
||||
One is an old-fashioned Web application and another is a modern REST based single page app.
|
||||
|
||||
## Installation
|
||||
Enter a given folder, either `showcase/` or `rest-showcase/` and start the app using Maven:
|
||||
|
||||
```
|
||||
mvn jetty:run
|
||||
```
|
||||
|
||||
then open your browser at http://localhost:8080 and navigate to a proper context.
|
||||
+1
-1
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-parent</artifactId>
|
||||
<version>6.0.0</version>
|
||||
<version>6.1.2</version>
|
||||
</parent>
|
||||
<artifactId>struts2-apps</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
@@ -24,12 +24,12 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-apps</artifactId>
|
||||
<version>6.0.0</version>
|
||||
<version>6.1.2</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-rest-showcase</artifactId>
|
||||
<packaging>war</packaging>
|
||||
<version>6.0.0</version>
|
||||
<version>6.1.2</version>
|
||||
<name>Struts 2 Rest Showcase Webapp</name>
|
||||
<description>Struts 2 Rest Showcase Example</description>
|
||||
|
||||
@@ -125,6 +125,7 @@
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<argLine>@{argLine}</argLine>
|
||||
<excludes>
|
||||
<exclude>it/**</exclude>
|
||||
<exclude>**/*$*</exclude>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
-->
|
||||
<!DOCTYPE struts PUBLIC
|
||||
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
|
||||
"http://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
"https://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
|
||||
|
||||
<struts>
|
||||
@@ -41,4 +41,4 @@
|
||||
<package name="rest-showcase" extends="rest-default">
|
||||
<global-allowed-methods>index,show,create,update,destroy,deleteConfirm,edit,editNew</global-allowed-methods>
|
||||
</package>
|
||||
</struts>
|
||||
</struts>
|
||||
|
||||
@@ -19,13 +19,14 @@
|
||||
* under the License.
|
||||
*/
|
||||
-->
|
||||
<web-app id="starter" version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
|
||||
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
|
||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
|
||||
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
|
||||
version="3.1">
|
||||
|
||||
<display-name>Struts 2 Rest Example</display-name>
|
||||
|
||||
|
||||
<!-- Filters -->
|
||||
<!-- START SNIPPET: filter -->
|
||||
<filter>
|
||||
|
||||
+15
-7
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-apps</artifactId>
|
||||
<version>6.0.0</version>
|
||||
<version>6.1.2</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-showcase</artifactId>
|
||||
@@ -121,6 +121,11 @@
|
||||
<artifactId>log4j-jcl</artifactId>
|
||||
<version>${log4j2.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-slf4j-impl</artifactId>
|
||||
<version>${log4j2.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>opensymphony</groupId>
|
||||
@@ -150,9 +155,9 @@
|
||||
|
||||
<!-- BeanValidation Example -->
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<groupId>org.hibernate.validator</groupId>
|
||||
<artifactId>hibernate-validator</artifactId>
|
||||
<version>6.1.2.Final</version>
|
||||
<version>${hibernate-validator.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
@@ -167,6 +172,9 @@
|
||||
<includes>
|
||||
<include>it.org.apache.struts2.showcase.*Test</include>
|
||||
</includes>
|
||||
<systemPropertyVariables>
|
||||
<http.port>8090</http.port>
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
@@ -191,15 +199,14 @@
|
||||
<stopKey>CTRL+C</stopKey>
|
||||
<stopPort>8999</stopPort>
|
||||
<systemProperties>
|
||||
<systemProperty>
|
||||
<name>log4j.configuration</name>
|
||||
<value>file:${basedir}/src/main/resources/log4j2.xml</value>
|
||||
</systemProperty>
|
||||
<systemProperty>
|
||||
<name>slf4j</name>
|
||||
<value>false</value>
|
||||
</systemProperty>
|
||||
</systemProperties>
|
||||
<httpConnector>
|
||||
<port>8090</port>
|
||||
</httpConnector>
|
||||
<scanIntervalSeconds>10</scanIntervalSeconds>
|
||||
<webAppSourceDirectory>${basedir}/src/main/webapp/</webAppSourceDirectory>
|
||||
<webAppConfig>
|
||||
@@ -230,6 +237,7 @@
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<argLine>@{argLine}</argLine>
|
||||
<excludes>
|
||||
<exclude>it/**</exclude>
|
||||
<exclude>**/*$*</exclude>
|
||||
|
||||
+158
-171
@@ -22,16 +22,13 @@ package org.apache.struts2.showcase.source;
|
||||
|
||||
import com.opensymphony.xwork2.ActionSupport;
|
||||
import com.opensymphony.xwork2.util.ClassLoaderUtil;
|
||||
import org.apache.struts2.ServletActionContext;
|
||||
import org.apache.struts2.action.ServletContextAware;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -42,202 +39,192 @@ import java.util.List;
|
||||
*/
|
||||
public class ViewSourceAction extends ActionSupport implements ServletContextAware {
|
||||
|
||||
private String page;
|
||||
private String className;
|
||||
private String config;
|
||||
private String page;
|
||||
private String className;
|
||||
private String config;
|
||||
|
||||
private List pageLines;
|
||||
private List classLines;
|
||||
private List configLines;
|
||||
private List<String> pageLines;
|
||||
private List<String> classLines;
|
||||
private List<String> configLines;
|
||||
|
||||
private int configLine;
|
||||
private int padding = 10;
|
||||
private int configLine;
|
||||
private int padding = 10;
|
||||
|
||||
private ServletContext servletContext;
|
||||
private ServletContext servletContext;
|
||||
|
||||
public String execute() throws MalformedURLException, IOException {
|
||||
public String execute() throws IOException {
|
||||
|
||||
if (page != null) {
|
||||
if (page != null) {
|
||||
|
||||
InputStream in = ClassLoaderUtil.getResourceAsStream(page.substring(page.indexOf("//") + 1), getClass());
|
||||
page = page.replace("//", "/");
|
||||
InputStream in = ClassLoaderUtil.getResourceAsStream(page.substring(page.indexOf("//") + 1), getClass());
|
||||
page = page.replace("//", "/");
|
||||
|
||||
if (in == null) {
|
||||
in = servletContext.getResourceAsStream(page);
|
||||
while (in == null && page.indexOf('/', 1) > 0) {
|
||||
page = page.substring(page.indexOf('/', 1));
|
||||
in = servletContext.getResourceAsStream(page);
|
||||
}
|
||||
}
|
||||
pageLines = read(in, -1);
|
||||
if (in == null) {
|
||||
in = servletContext.getResourceAsStream(page);
|
||||
while (in == null && page.indexOf('/', 1) > 0) {
|
||||
page = page.substring(page.indexOf('/', 1));
|
||||
in = servletContext.getResourceAsStream(page);
|
||||
}
|
||||
}
|
||||
pageLines = read(in, -1);
|
||||
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
|
||||
if (className != null) {
|
||||
className = "/" + className.replace('.', '/') + ".java";
|
||||
InputStream in = getClass().getResourceAsStream(className);
|
||||
if (in == null) {
|
||||
in = servletContext.getResourceAsStream("/WEB-INF/src" + className);
|
||||
}
|
||||
classLines = read(in, -1);
|
||||
if (className != null) {
|
||||
className = "/" + className.replace('.', '/') + ".java";
|
||||
InputStream in = getClass().getResourceAsStream(className);
|
||||
if (in == null) {
|
||||
in = servletContext.getResourceAsStream("/WEB-INF/src/java" + className);
|
||||
}
|
||||
classLines = read(in, -1);
|
||||
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
|
||||
final String rootPath = ServletActionContext.getServletContext().getRealPath("/");
|
||||
final String rootPathUnix = (rootPath != null ? rootPath.replace(File.separator, "/") : null); // Make path Unix-like for comparison (e.g. on Windows)
|
||||
final String rootPathFileURI = "file://" + rootPathUnix;
|
||||
final String collapsedRootPathFileURI = rootPathFileURI.replace("//", "/"); // Config string may have been transformed
|
||||
final String rootPathWarFileURI = "war:file://" + rootPathUnix;
|
||||
final String collapsedRootPathWarFileURI = rootPathWarFileURI.replace("//", "/"); // Config string may have been transformed
|
||||
|
||||
if (config != null && (rootPath == null || config.startsWith(rootPath) ||
|
||||
config.startsWith(rootPathFileURI) || config.startsWith(collapsedRootPathFileURI) ||
|
||||
config.startsWith(rootPathWarFileURI) || config.startsWith(collapsedRootPathWarFileURI))) {
|
||||
int pos = config.lastIndexOf(':');
|
||||
configLine = Integer.parseInt(config.substring(pos + 1));
|
||||
config = config.substring(0, pos).replace("//", "/");
|
||||
configLines = read(new URL(config).openStream(), configLine);
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
if (config != null && config.startsWith("file:/")) {
|
||||
int pos = config.lastIndexOf(':');
|
||||
configLine = Integer.parseInt(config.substring(pos + 1));
|
||||
configLines = read(new URL(config.substring(0, pos)).openStream(), configLine);
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param className the className to set
|
||||
*/
|
||||
public void setClassName(String className) {
|
||||
if (className != null && className.trim().length() > 0) {
|
||||
this.className = className;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param className the className to set
|
||||
*/
|
||||
public void setClassName(String className) {
|
||||
if (className != null && className.trim().length() > 0) {
|
||||
this.className = className;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param config the config to set
|
||||
*/
|
||||
public void setConfig(String config) {
|
||||
if (config != null && config.trim().length() > 0) {
|
||||
this.config = config;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param config the config to set
|
||||
*/
|
||||
public void setConfig(String config) {
|
||||
if (config != null && config.trim().length() > 0) {
|
||||
this.config = config;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param page the page to set
|
||||
*/
|
||||
public void setPage(String page) {
|
||||
if (page != null && page.trim().length() > 0) {
|
||||
this.page = page;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param page the page to set
|
||||
*/
|
||||
public void setPage(String page) {
|
||||
if (page != null && page.trim().length() > 0) {
|
||||
this.page = page;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param padding the padding to set
|
||||
*/
|
||||
public void setPadding(int padding) {
|
||||
this.padding = padding;
|
||||
}
|
||||
/**
|
||||
* @param padding the padding to set
|
||||
*/
|
||||
public void setPadding(int padding) {
|
||||
this.padding = padding;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the classLines
|
||||
*/
|
||||
public List getClassLines() {
|
||||
return classLines;
|
||||
}
|
||||
/**
|
||||
* @return the classLines
|
||||
*/
|
||||
public List<String> getClassLines() {
|
||||
return classLines;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the configLines
|
||||
*/
|
||||
public List getConfigLines() {
|
||||
return configLines;
|
||||
}
|
||||
/**
|
||||
* @return the configLines
|
||||
*/
|
||||
public List<String> getConfigLines() {
|
||||
return configLines;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the pageLines
|
||||
*/
|
||||
public List getPageLines() {
|
||||
return pageLines;
|
||||
}
|
||||
/**
|
||||
* @return the pageLines
|
||||
*/
|
||||
public List<String> getPageLines() {
|
||||
return pageLines;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the className
|
||||
*/
|
||||
public String getClassName() {
|
||||
return className;
|
||||
}
|
||||
/**
|
||||
* @return the className
|
||||
*/
|
||||
public String getClassName() {
|
||||
return className;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the config
|
||||
*/
|
||||
public String getConfig() {
|
||||
return config;
|
||||
}
|
||||
/**
|
||||
* @return the config
|
||||
*/
|
||||
public String getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the page
|
||||
*/
|
||||
public String getPage() {
|
||||
return page;
|
||||
}
|
||||
/**
|
||||
* @return the page
|
||||
*/
|
||||
public String getPage() {
|
||||
return page;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the configLine
|
||||
*/
|
||||
public int getConfigLine() {
|
||||
return configLine;
|
||||
}
|
||||
/**
|
||||
* @return the configLine
|
||||
*/
|
||||
public int getConfigLine() {
|
||||
return configLine;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the padding
|
||||
*/
|
||||
public int getPadding() {
|
||||
return padding;
|
||||
}
|
||||
/**
|
||||
* @return the padding
|
||||
*/
|
||||
public int getPadding() {
|
||||
return padding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads in a stream, optionally only including the target line number
|
||||
* and its padding
|
||||
*
|
||||
* @param in The input stream
|
||||
* @param targetLineNumber The target line number, negative to read all
|
||||
* @return A list of lines
|
||||
*/
|
||||
private List read(InputStream in, int targetLineNumber) {
|
||||
List snippet = null;
|
||||
if (in != null) {
|
||||
snippet = new ArrayList();
|
||||
int startLine = 0;
|
||||
int endLine = Integer.MAX_VALUE;
|
||||
if (targetLineNumber > 0) {
|
||||
startLine = targetLineNumber - padding;
|
||||
endLine = targetLineNumber + padding;
|
||||
}
|
||||
try {
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
|
||||
/**
|
||||
* Reads in a stream, optionally only including the target line number
|
||||
* and its padding
|
||||
*
|
||||
* @param in The input stream
|
||||
* @param targetLineNumber The target line number, negative to read all
|
||||
* @return A list of lines
|
||||
*/
|
||||
private List<String> read(InputStream in, int targetLineNumber) {
|
||||
List<String> snippet = null;
|
||||
if (in != null) {
|
||||
snippet = new ArrayList<>();
|
||||
int startLine = 0;
|
||||
int endLine = Integer.MAX_VALUE;
|
||||
if (targetLineNumber > 0) {
|
||||
startLine = targetLineNumber - padding;
|
||||
endLine = targetLineNumber + padding;
|
||||
}
|
||||
try {
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
|
||||
|
||||
int lineno = 0;
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
lineno++;
|
||||
if (lineno >= startLine && lineno <= endLine) {
|
||||
snippet.add(line);
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
// ignoring as snippet not available isn't a big deal
|
||||
}
|
||||
}
|
||||
return snippet;
|
||||
}
|
||||
int lineno = 0;
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
lineno++;
|
||||
if (lineno >= startLine && lineno <= endLine) {
|
||||
snippet.add(line);
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
// ignoring as snippet not available isn't a big deal
|
||||
}
|
||||
}
|
||||
return snippet;
|
||||
}
|
||||
|
||||
public void withServletContext(ServletContext arg0) {
|
||||
this.servletContext = arg0;
|
||||
}
|
||||
public void withServletContext(ServletContext arg0) {
|
||||
this.servletContext = arg0;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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.showcase.wait;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.interceptor.exec.ExecutorProvider;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.LinkedBlockingDeque;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class ThreadPoolExecutorProvider implements ExecutorProvider {
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(ThreadPoolExecutorProvider.class);
|
||||
|
||||
private final ExecutorService executor;
|
||||
|
||||
public ThreadPoolExecutorProvider() {
|
||||
this.executor = new ThreadPoolExecutor(1, 2, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingDeque<>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Runnable task) {
|
||||
LOG.info("Executing task: {}", task);
|
||||
executor.execute(task);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShutdown() {
|
||||
return executor.isShutdown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
LOG.info("Shutting down executor");
|
||||
executor.shutdown();
|
||||
}
|
||||
}
|
||||
@@ -22,15 +22,14 @@
|
||||
<Configuration>
|
||||
<Appenders>
|
||||
<Console name="STDOUT" target="SYSTEM_OUT">
|
||||
<PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
|
||||
<PatternLayout pattern="[%-5p] %C{2} (%F:%L) - %m%n"/>
|
||||
</Console>
|
||||
</Appenders>
|
||||
<Loggers>
|
||||
<Logger name="com.opensymphony.xwork2" level="info"/>
|
||||
<Logger name="org.apache.struts2" level="info"/>
|
||||
<Logger name="org.springframework" level="info"/>
|
||||
<Root level="info">
|
||||
<AppenderRef ref="STDOUT"/>
|
||||
</Root>
|
||||
<Logger name="org.apache.struts2" level="info"/>
|
||||
<Logger name="com.opensymphony.xwork2" level="info"/>
|
||||
</Loggers>
|
||||
</Configuration>
|
||||
</Configuration>
|
||||
|
||||
+7
-7
@@ -21,31 +21,31 @@
|
||||
-->
|
||||
<!DOCTYPE validators PUBLIC
|
||||
"-//Apache Struts//XWork Validator 1.0.2//EN"
|
||||
"http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
|
||||
|
||||
"https://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
|
||||
|
||||
<validators>
|
||||
<field name="description1">
|
||||
<field-validator type="requiredstring">
|
||||
<message>Description1 Is Required !!!</message>
|
||||
</field-validator>
|
||||
</field>
|
||||
|
||||
|
||||
<field name="description2">
|
||||
<field-validator type="requiredstring">
|
||||
<message>Description2 Is Required !!!</message>
|
||||
</field-validator>
|
||||
</field>
|
||||
|
||||
|
||||
<field name="description3">
|
||||
<field-validator type="requiredstring">
|
||||
<message>Description3 Is Required !!!</message>
|
||||
</field-validator>
|
||||
</field>
|
||||
|
||||
|
||||
<field name="description4">
|
||||
<field-validator type="requiredstring">
|
||||
<message>Description4 Is Required !!!</message>
|
||||
</field-validator>
|
||||
</field>
|
||||
</validators>
|
||||
|
||||
</validators>
|
||||
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
-->
|
||||
<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0//EN" "http://struts.apache.org/dtds/xwork-validator-1.0.dtd">
|
||||
<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0//EN" "https://struts.apache.org/dtds/xwork-validator-1.0.dtd">
|
||||
<validators>
|
||||
<!-- Field-Validator Syntax -->
|
||||
<field name="currentEmployee.empId">
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
-->
|
||||
<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0//EN" "http://struts.apache.org/dtds/xwork-validator-1.0.dtd">
|
||||
<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0//EN" "https://struts.apache.org/dtds/xwork-validator-1.0.dtd">
|
||||
<validators>
|
||||
<!-- Field-Validator Syntax -->
|
||||
<field name="currentSkill.name">
|
||||
|
||||
+2
-3
@@ -21,7 +21,7 @@
|
||||
-->
|
||||
<!DOCTYPE validators PUBLIC
|
||||
"-//Apache Struts//XWork Validator 1.0.2//EN"
|
||||
"http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
|
||||
"https://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
|
||||
|
||||
<validators>
|
||||
<field name="upload">
|
||||
@@ -35,5 +35,4 @@
|
||||
<message>Caption cannot be empty</message>
|
||||
</field-validator>
|
||||
</field>
|
||||
</validators>
|
||||
|
||||
</validators>
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
-->
|
||||
<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0//EN" "http://struts.apache.org/dtds/xwork-validator-1.0.dtd">
|
||||
<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0//EN" "https://struts.apache.org/dtds/xwork-validator-1.0.dtd">
|
||||
<validators>
|
||||
<field name="person">
|
||||
<field-validator type="visitor">
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
-->
|
||||
<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0//EN" "http://struts.apache.org/dtds/xwork-validator-1.0.dtd">
|
||||
<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0//EN" "https://struts.apache.org/dtds/xwork-validator-1.0.dtd">
|
||||
<validators>
|
||||
<field name="name">
|
||||
<field-validator type="requiredstring">
|
||||
|
||||
+6
-6
@@ -21,8 +21,8 @@
|
||||
-->
|
||||
<!DOCTYPE validators PUBLIC
|
||||
"-//Apache Struts//XWork Validator 1.0.2//EN"
|
||||
"http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
|
||||
|
||||
"https://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
|
||||
|
||||
<validators>
|
||||
<field name="value">
|
||||
<field-validator type="requiredstring">
|
||||
@@ -30,13 +30,13 @@
|
||||
<message>Value must not be empty</message>
|
||||
</field-validator>
|
||||
</field>
|
||||
|
||||
|
||||
|
||||
|
||||
<field name="count">
|
||||
<field-validator type="int">
|
||||
<message>Count must be an integer</message>
|
||||
</field-validator>
|
||||
</field-validator>
|
||||
</field>
|
||||
</validators>
|
||||
</validators>
|
||||
|
||||
|
||||
|
||||
+4
-4
@@ -21,10 +21,10 @@
|
||||
-->
|
||||
<!DOCTYPE validators PUBLIC
|
||||
"-//Apache Struts//XWork Validator 1.0//EN"
|
||||
"http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
|
||||
|
||||
<!-- START SNIPPET: fieldValidatorsExample -->
|
||||
|
||||
"https://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
|
||||
|
||||
<!-- START SNIPPET: fieldValidatorsExample -->
|
||||
|
||||
<validators>
|
||||
<field name="requiredValidatorField">
|
||||
<field-validator type="required">
|
||||
|
||||
+5
-5
@@ -19,12 +19,12 @@
|
||||
* under the License.
|
||||
*/
|
||||
-->
|
||||
<!DOCTYPE validators PUBLIC
|
||||
<!DOCTYPE validators PUBLIC
|
||||
"-//Apache Struts//XWork Validator 1.0//EN"
|
||||
"http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
|
||||
|
||||
<!-- START SNIPPET: fieldValidatorsExample -->
|
||||
|
||||
"https://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
|
||||
|
||||
<!-- START SNIPPET: fieldValidatorsExample -->
|
||||
|
||||
<validators>
|
||||
<field name="requiredValidatorField">
|
||||
<field-validator type="required">
|
||||
|
||||
+6
-6
@@ -19,13 +19,13 @@
|
||||
* under the License.
|
||||
*/
|
||||
-->
|
||||
<!DOCTYPE validators PUBLIC
|
||||
<!DOCTYPE validators PUBLIC
|
||||
"-//Apache Struts//XWork Validator 1.0//EN"
|
||||
"http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
|
||||
|
||||
|
||||
<!-- START SNIPPET: nonFieldValidatorsExample -->
|
||||
|
||||
"https://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
|
||||
|
||||
|
||||
<!-- START SNIPPET: nonFieldValidatorsExample -->
|
||||
|
||||
<validators>
|
||||
<validator type="expression">
|
||||
<param name="expression"><![CDATA[ ( (someText == someTextRetype) && (someTextRetype == someTextRetypeAgain) ) ]]></param>
|
||||
|
||||
+2
-2
@@ -19,11 +19,11 @@
|
||||
* under the License.
|
||||
*/
|
||||
-->
|
||||
<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.2//EN" "http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
|
||||
<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.2//EN" "https://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
|
||||
<!-- START SNIPPET: quizValidators -->
|
||||
<!--
|
||||
Add the following DOCTYPE declaration as first line of your XXX-validation.xml file:
|
||||
<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.2//EN" "http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
|
||||
<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.2//EN" "https://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
|
||||
-->
|
||||
<validators>
|
||||
<field name="name">
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@
|
||||
-->
|
||||
<!DOCTYPE validators PUBLIC
|
||||
"-//Apache Struts//XWork Validator 1.0//EN"
|
||||
"http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
|
||||
"https://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
|
||||
|
||||
<validators>
|
||||
<field name="name">
|
||||
|
||||
+5
-5
@@ -19,17 +19,17 @@
|
||||
* under the License.
|
||||
*/
|
||||
-->
|
||||
<!DOCTYPE validators PUBLIC
|
||||
<!DOCTYPE validators PUBLIC
|
||||
"-//Apache Struts//XWork Validator 1.0//EN"
|
||||
"http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
|
||||
|
||||
"https://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
|
||||
|
||||
<validators>
|
||||
<field name="name">
|
||||
<field-validator type="requiredstring">
|
||||
<message>Name Required</message>
|
||||
</field-validator>
|
||||
</field>
|
||||
<field name="age">
|
||||
<field name="age">
|
||||
<field-validator type="int">
|
||||
<param name="min">1</param>
|
||||
<param name="max">100</param>
|
||||
@@ -41,6 +41,6 @@
|
||||
<message>Birthday Required</message>
|
||||
</field-validator>
|
||||
</field>
|
||||
</validators>
|
||||
</validators>
|
||||
|
||||
|
||||
|
||||
+3
-3
@@ -19,10 +19,10 @@
|
||||
* under the License.
|
||||
*/
|
||||
-->
|
||||
<!DOCTYPE validators PUBLIC
|
||||
<!DOCTYPE validators PUBLIC
|
||||
"-//Apache Struts//XWork Validator 1.0//EN"
|
||||
"http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
|
||||
|
||||
"https://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
|
||||
|
||||
<!-- START SNIPPET: visitorValidatorsExample -->
|
||||
|
||||
<validators>
|
||||
|
||||
@@ -21,12 +21,12 @@
|
||||
-->
|
||||
<!DOCTYPE struts PUBLIC
|
||||
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
|
||||
"http://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
|
||||
"https://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
|
||||
<struts>
|
||||
<package name="actionchaining" extends="struts-default" namespace="/actionchaining">
|
||||
<action name="actionChain1" class="org.apache.struts2.showcase.actionchaining.ActionChain1">
|
||||
<result type="chain">actionChain2</result>
|
||||
<result type="chain">actionChain2</result>
|
||||
</action>
|
||||
<action name="actionChain2" class="org.apache.struts2.showcase.actionchaining.ActionChain2">
|
||||
<result type="chain">actionChain3</result>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
-->
|
||||
<!DOCTYPE struts PUBLIC
|
||||
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
|
||||
"http://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
"https://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
|
||||
<struts>
|
||||
<package name="async" extends="json-default" namespace="/async">
|
||||
|
||||
@@ -21,15 +21,15 @@
|
||||
-->
|
||||
<!DOCTYPE struts PUBLIC
|
||||
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
|
||||
"http://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
|
||||
"https://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
|
||||
<struts>
|
||||
<package name="conversion" namespace="/conversion" extends="struts-default">
|
||||
|
||||
|
||||
<action name="index">
|
||||
<result>/WEB-INF/conversion/index.jsp</result>
|
||||
</action>
|
||||
|
||||
|
||||
<!-- Example populating a List inside an Action -->
|
||||
<action name="enterPersonsInfo" method="input"
|
||||
class="org.apache.struts2.showcase.conversion.PersonAction">
|
||||
@@ -49,8 +49,8 @@
|
||||
<action name="showPersonJavaCode">
|
||||
<result type="plainText">/WEB-INF/conversion/Person.java.txt</result>
|
||||
</action>
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- Example populating a Set inside an Action -->
|
||||
<action name="enterAddressesInfo" class="org.apache.struts2.showcase.conversion.AddressAction" method="input">
|
||||
<result>/WEB-INF/conversion/enterAddressInfo.jsp</result>
|
||||
@@ -68,9 +68,9 @@
|
||||
<action name="showAddressJavaCode">
|
||||
<result type="plainText">/WEB-INF/conversion/Address.java.txt</result>
|
||||
</action>
|
||||
|
||||
|
||||
<!-- Example populating a List with Tiger 5 Enum -->
|
||||
|
||||
|
||||
<!-- Example populating a List with Tiger 5 Enum -->
|
||||
<action name="enterOperationEnumInfo" class="org.apache.struts2.showcase.conversion.OperationsEnumAction" method="input">
|
||||
<result>/WEB-INF/conversion/enterOperations.jsp</result>
|
||||
</action>
|
||||
@@ -93,6 +93,6 @@
|
||||
<action name="showOperationsEnumActionConversionProperties">
|
||||
<result type="plainText">/WEB-INF/conversion/OperationsEnumActionConversion.txt</result>
|
||||
</action>
|
||||
|
||||
|
||||
</package>
|
||||
</struts>
|
||||
</struts>
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
-->
|
||||
<!DOCTYPE struts PUBLIC
|
||||
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
|
||||
"https://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
|
||||
<struts>
|
||||
<package name="dispatcher" extends="struts-default" namespace="/dispatcher">
|
||||
|
||||
<action name="dispatch">
|
||||
<result type="dispatcher">
|
||||
/WEB-INF/dispatcher/dispatch-result.jsp
|
||||
</result>
|
||||
</action>
|
||||
|
||||
<action name="forward">
|
||||
<result type="dispatcher">/dispatcher/dispatch.action</result>
|
||||
</action>
|
||||
|
||||
</package>
|
||||
</struts>
|
||||
@@ -21,7 +21,7 @@
|
||||
-->
|
||||
<!DOCTYPE struts PUBLIC
|
||||
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
|
||||
"http://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
"https://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
|
||||
<struts>
|
||||
<package name="filedownload" extends="struts-default" namespace="/filedownload">
|
||||
|
||||
@@ -21,11 +21,11 @@
|
||||
-->
|
||||
<!DOCTYPE struts PUBLIC
|
||||
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
|
||||
"http://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
"https://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
|
||||
<struts>
|
||||
<package name="fileupload" extends="struts-default" namespace="/fileupload">
|
||||
|
||||
|
||||
<action name="upload" class="org.apache.struts2.showcase.fileupload.FileUploadAction" method="input">
|
||||
<result>/WEB-INF/fileupload/upload.jsp</result>
|
||||
</action>
|
||||
@@ -34,11 +34,11 @@
|
||||
<result name="input">/WEB-INF/fileupload/upload.jsp</result>
|
||||
<result>/WEB-INF/fileupload/upload-success.jsp</result>
|
||||
</action>
|
||||
|
||||
|
||||
<action name="multipleUploadUsingList">
|
||||
<result>/WEB-INF/fileupload/multipleUploadUsingList.jsp</result>
|
||||
</action>
|
||||
|
||||
|
||||
<action name="doMultipleUploadUsingList" class="org.apache.struts2.showcase.fileupload.MultipleFileUploadUsingListAction" method="upload">
|
||||
<result name="input">/WEB-INF/fileupload/multipleUploadUsingList.jsp</result>
|
||||
<result>/WEB-INF/fileupload/multiple-success.jsp</result>
|
||||
|
||||
@@ -21,16 +21,16 @@
|
||||
-->
|
||||
<!DOCTYPE struts PUBLIC
|
||||
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
|
||||
"http://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
"https://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
|
||||
<struts>
|
||||
<package name="freemarker" namespace="/freemarker" extends="struts-default">
|
||||
<action name="customFreemarkerManagerDemo">
|
||||
<result type="freemarker">/WEB-INF/freemarker/customFreemarkerManagerUsage.ftl</result>
|
||||
</action>
|
||||
|
||||
|
||||
<action name="standardTags" class="org.apache.struts2.showcase.freemarker.StandardTagsAction">
|
||||
<result type="freemarker">/WEB-INF/freemarker/standardTags.ftl</result>
|
||||
</action>
|
||||
</package>
|
||||
</struts>
|
||||
</struts>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
-->
|
||||
<!DOCTYPE struts PUBLIC
|
||||
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
|
||||
"http://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
"https://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
|
||||
<struts>
|
||||
<package name="hangman" extends="struts-default" namespace="/hangman">
|
||||
@@ -41,9 +41,9 @@
|
||||
<result type="freemarker">/WEB-INF/hangman/hangmanNonAjax.ftl</result>
|
||||
</action>
|
||||
</package>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<package name="hangman-ajax" extends="struts-default" namespace="/hangman/ajax">
|
||||
<action name="blank">
|
||||
<result type="freemarker">/WEB-INF/hangman/blank.ftl</result>
|
||||
@@ -61,4 +61,4 @@
|
||||
<result type="freemarker">/WEB-INF/hangman/updateGuessLeft.ftl</result>
|
||||
</action>
|
||||
</package>
|
||||
</struts>
|
||||
</struts>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
-->
|
||||
<!DOCTYPE struts PUBLIC
|
||||
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
|
||||
"http://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
"https://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
|
||||
<struts>
|
||||
<package name="interactive" namespace="/interactive" extends="struts-default">
|
||||
@@ -38,4 +38,4 @@
|
||||
</action>
|
||||
<action name="example" class="org.apache.struts2.showcase.action.ExampleAction" />
|
||||
</package>
|
||||
</struts>
|
||||
</struts>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
-->
|
||||
<!DOCTYPE struts PUBLIC
|
||||
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
|
||||
"http://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
"https://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
|
||||
<struts>
|
||||
<package name="modelDriven" extends="struts-default" namespace="/modelDriven">
|
||||
@@ -29,11 +29,10 @@
|
||||
<action name="modelDriven" class="org.apache.struts2.showcase.modelDriven.ModelDrivenAction" method="input">
|
||||
<result>/WEB-INF/modelDriven/modelDriven.jsp</result>
|
||||
</action>
|
||||
|
||||
|
||||
<!-- Display the result page whose content is populated using the Model-Driven technique -->
|
||||
<action name="modelDrivenResult" class="org.apache.struts2.showcase.modelDriven.ModelDrivenAction">
|
||||
<result>/WEB-INF/modelDriven/modelDrivenResult.jsp</result>
|
||||
</action>
|
||||
</package>
|
||||
</struts>
|
||||
|
||||
</struts>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
-->
|
||||
<!DOCTYPE struts PUBLIC
|
||||
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
|
||||
"http://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
"https://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
|
||||
<!-- START SNIPPET: xworkSample -->
|
||||
|
||||
|
||||
@@ -21,14 +21,14 @@
|
||||
-->
|
||||
<!DOCTYPE struts PUBLIC
|
||||
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
|
||||
"http://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
|
||||
"https://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
|
||||
<struts>
|
||||
|
||||
|
||||
<!-- ================================== -->
|
||||
<!-- === Package for ActionTag Demo === -->
|
||||
<!-- ================================== -->
|
||||
|
||||
|
||||
<package name="actionTag" extends="struts-default" namespace="/tags/non-ui/actionTag">
|
||||
<action name="showActionTagDemo" class="org.apache.struts2.showcase.tag.nonui.actiontag.ActionTagDemo" method="show">
|
||||
<result>/WEB-INF/tags/non-ui/actionTag/showActionTagDemo.jsp</result>
|
||||
@@ -46,11 +46,11 @@
|
||||
<result type="plainText">/WEB-INF/tags/non-ui/actionTag/showActionTagDemo.jsp</result>
|
||||
</action>
|
||||
</package>
|
||||
|
||||
|
||||
<!-- ==================================== -->
|
||||
<!-- === Package for IteratorGeneratorTag Demo === -->
|
||||
<!-- ==================================== -->
|
||||
|
||||
|
||||
<package name="iteratorGeneratorTag" extends="struts-default" namespace="/tags/non-ui/iteratorGeneratorTag">
|
||||
<action name="showGeneratorTagDemo" class="org.apache.struts2.showcase.tag.nonui.iteratortag.IteratorGeneratorTagDemo" method="input">
|
||||
<result>/WEB-INF/tags/non-ui/iteratorTag/showIteratorGeneratorTagDemo.jsp</result>
|
||||
@@ -60,8 +60,8 @@
|
||||
<result>/WEB-INF/tags/non-ui/iteratorTag/iteratorGeneratorTagDemoResult.jsp</result>
|
||||
</action>
|
||||
</package>
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- ===================================== -->
|
||||
<!-- === Package for AppendIteratorTag Demo === -->
|
||||
<!-- ========================================== -->
|
||||
@@ -74,8 +74,8 @@
|
||||
<result>/WEB-INF/tags/non-ui/iteratorTag/appendIteratorTagDemoResult.jsp</result>
|
||||
</action>
|
||||
</package>
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- ====================================== -->
|
||||
<!-- === Package for MergeIteratorTag Demo === -->
|
||||
<!-- ========================================= -->
|
||||
@@ -88,7 +88,7 @@
|
||||
<result>/WEB-INF/tags/non-ui/iteratorTag/mergeIteratorTagDemoResult.jsp</result>
|
||||
</action>
|
||||
</package>
|
||||
|
||||
|
||||
<!-- ============================================= -->
|
||||
<!-- === Package for SubsetIteratorTag Demo === -->
|
||||
<!-- =========================================== -->
|
||||
@@ -101,14 +101,14 @@
|
||||
<result>/WEB-INF/tags/non-ui/iteratorTag/subsetIteratorTagDemoResult.jsp</result>
|
||||
</action>
|
||||
</package>
|
||||
|
||||
|
||||
<!-- ========================================= -->
|
||||
<!-- === Package for Action Prefix Example === -->
|
||||
<!-- ========================================= -->
|
||||
<package name="actionPrefix" extends="struts-default" namespace="/tags/non-ui/actionPrefix">
|
||||
<action name="actionPrefixExampleUsingFreemarker">
|
||||
<result type="freemarker">/WEB-INF/tags/non-ui/actionPrefix/actionPrefixExample.ftl</result>
|
||||
</action>
|
||||
</action>
|
||||
<action name="submit" class="org.apache.struts2.showcase.tag.nonui.actionPrefix.SubmitAction">
|
||||
<result type="freemarker">/WEB-INF/tags/non-ui/actionPrefix/normalSubmit.ftl</result>
|
||||
</action>
|
||||
@@ -131,7 +131,7 @@
|
||||
<result type="plainText">/WEB-INF/tags/non-ui/actionPrefix/actionPrefixExample.ftl</result>
|
||||
</action>
|
||||
</package>
|
||||
|
||||
|
||||
<!-- ========================================== -->
|
||||
<!-- === Package for If Tag Test / Examples === -->
|
||||
<!-- ========================================== -->
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
-->
|
||||
<!DOCTYPE struts PUBLIC
|
||||
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
|
||||
"http://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
"https://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
|
||||
<struts>
|
||||
<package name="ui-tags" extends="velocity-default" namespace="/tags/ui">
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
-->
|
||||
<!DOCTYPE struts PUBLIC
|
||||
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
|
||||
"http://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
"https://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
|
||||
<struts>
|
||||
<include file="struts-tags-ui.xml"/>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
-->
|
||||
<!DOCTYPE struts PUBLIC
|
||||
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
|
||||
"http://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
"https://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
|
||||
<struts>
|
||||
<package name="tiles" extends="tiles-default" namespace="/tiles">
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
-->
|
||||
<!DOCTYPE struts PUBLIC
|
||||
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
|
||||
"http://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
"https://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
<struts>
|
||||
<package name="token" extends="struts-default" namespace="/token">
|
||||
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
-->
|
||||
<!DOCTYPE struts PUBLIC
|
||||
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
|
||||
"http://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
|
||||
"https://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
|
||||
<struts>
|
||||
|
||||
<constant name="struts.beanValidation.providerClass" value="org.hibernate.validator.HibernateValidator"/>
|
||||
@@ -74,7 +74,7 @@
|
||||
<action name="ajaxFormSubmitSuccess" class="org.apache.struts2.showcase.validation.AjaxFormSubmitSuccessAction">
|
||||
<result>/WEB-INF/validation/ajaxFormSubmitSuccess.jsp</result>
|
||||
</action>
|
||||
|
||||
|
||||
</package>
|
||||
|
||||
|
||||
@@ -83,46 +83,46 @@
|
||||
<action name="list">
|
||||
<result>index.jsp</result>
|
||||
</action>
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- ======================== -->
|
||||
<!-- === Field Validators === -->
|
||||
<!-- ======================== -->
|
||||
|
||||
|
||||
<action name="showFieldValidatorsExamples" class="org.apache.struts2.showcase.validation.FieldValidatorsExampleAction" method="input">
|
||||
<result name="input" type="dispatcher">/WEB-INF/validation/fieldValidatorsExample.jsp</result>
|
||||
</action>
|
||||
|
||||
|
||||
<action name="submitFieldValidatorsExamples" class="org.apache.struts2.showcase.validation.FieldValidatorsExampleAction" method="submit">
|
||||
<result name="input" type="dispatcher">/WEB-INF/validation/fieldValidatorsExample.jsp</result>
|
||||
<result type="dispatcher">/WEB-INF/validation/successFieldValidatorsExample.jsp</result>
|
||||
</action>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- ============================ -->
|
||||
<!-- === Non Field Validators === -->
|
||||
<!-- ============================ -->
|
||||
|
||||
|
||||
<action name="showNonFieldValidatorsExamples" class="org.apache.struts2.showcase.validation.NonFieldValidatorsExampleAction" method="input">
|
||||
<result name="input">/WEB-INF/validation/nonFieldValidatorsExample.jsp</result>
|
||||
</action>
|
||||
|
||||
|
||||
<action name="submitNonFieldValidatorsExamples" class="org.apache.struts2.showcase.validation.NonFieldValidatorsExampleAction" method="submit">
|
||||
<result name="input">/WEB-INF/validation/nonFieldValidatorsExample.jsp</result>
|
||||
<result>/WEB-INF/validation/successNonFieldValidatorsExample.jsp</result>
|
||||
</action>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- ========================== -->
|
||||
<!-- === Visitor Validators === -->
|
||||
<!-- ========================== -->
|
||||
|
||||
|
||||
<action name="showVisitorValidatorsExamples" class="org.apache.struts2.showcase.validation.VisitorValidatorsExampleAction" method="input">
|
||||
<result name="input">/WEB-INF/validation/visitorValidatorsExample.jsp</result>
|
||||
</action>
|
||||
|
||||
|
||||
<action name="submitVisitorValidatorsExamples" class="org.apache.struts2.showcase.validation.VisitorValidatorsExampleAction" method="submit">
|
||||
<result name="input">/WEB-INF/validation/visitorValidatorsExample.jsp</result>
|
||||
<result>/WEB-INF/validation/successVisitorValidatorsExample.jsp</result>
|
||||
@@ -146,7 +146,7 @@
|
||||
<!-- =========================================== -->
|
||||
<!-- === Store Error Messages Across Request === -->
|
||||
<!-- =========================================== -->
|
||||
|
||||
|
||||
<action name="submitApplication" class="org.apache.struts2.showcase.validation.SubmitApplication" method="submitApplication">
|
||||
<interceptor-ref name="store">
|
||||
<param name="operationMode">STORE</param>
|
||||
@@ -173,7 +173,7 @@
|
||||
<action name="cancelApplication" class="org.apache.struts2.showcase.validation.SubmitApplication" method="cancelApplication">
|
||||
<result>/WEB-INF/validation/storeErrorsAcrossRequestCancel.jsp</result>
|
||||
</action>
|
||||
|
||||
|
||||
</package>
|
||||
</struts>
|
||||
|
||||
|
||||
|
||||
@@ -21,10 +21,17 @@
|
||||
-->
|
||||
<!DOCTYPE struts PUBLIC
|
||||
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
|
||||
"http://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
"https://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
|
||||
<struts>
|
||||
|
||||
<bean type="org.apache.struts2.interceptor.exec.ExecutorProvider" class="org.apache.struts2.showcase.wait.ThreadPoolExecutorProvider"/>
|
||||
|
||||
<package name="wait" extends="struts-default" namespace="/wait">
|
||||
<default-action-ref name="index"/>
|
||||
<action name="index">
|
||||
<result>/WEB-INF/wait/index.jsp</result>
|
||||
</action>
|
||||
|
||||
<action name="example1">
|
||||
<result>/WEB-INF/wait/example1.jsp</result>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
-->
|
||||
<!DOCTYPE struts PUBLIC
|
||||
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
|
||||
"http://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
"https://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
|
||||
<struts>
|
||||
<package name="xslt" extends="struts-default" namespace="/xslt">
|
||||
@@ -36,7 +36,7 @@
|
||||
<param name="exposedValue">info.classpath</param>
|
||||
</result>
|
||||
</action>
|
||||
|
||||
|
||||
<action name="jvmInfoRaw" class="org.apache.struts2.showcase.xslt.JVMAction">
|
||||
<result type="xslt">
|
||||
<param name="exposedValue">info</param>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
-->
|
||||
<!DOCTYPE struts PUBLIC
|
||||
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
|
||||
"http://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
"https://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
|
||||
<!-- START SNIPPET: xworkSample -->
|
||||
<struts>
|
||||
@@ -78,6 +78,8 @@
|
||||
|
||||
<include file="struts-async.xml" />
|
||||
|
||||
<include file="struts-dispatcher.xml" />
|
||||
|
||||
<package name="default" extends="struts-default">
|
||||
<interceptors>
|
||||
<interceptor-stack name="crudStack">
|
||||
|
||||
@@ -64,14 +64,14 @@
|
||||
<title><decorator:title default="Struts2 Showcase"/></title>
|
||||
|
||||
<s:url var="bootstrapCss" value='/styles/bootstrap.css' encode='false' includeParams='none'/>
|
||||
<s:link href="%{bootstrapCss}" rel="stylesheet" type="text/css" media="all"></s:link>
|
||||
<s:link href="%{bootstrapCss}" rel="stylesheet" type="text/css" media="all"/>
|
||||
<s:url var="mainCss" value='/styles/main.css' encode='false' includeParams='none'/>
|
||||
<s:link href="%{mainCss}" rel="stylesheet" type="text/css" media="all"></s:link>
|
||||
<s:link href="%{mainCss}" rel="stylesheet" type="text/css" media="all"/>
|
||||
|
||||
<s:url var="jqueryJs" value='/js/jquery-2.1.4.min.js' encode='false' includeParams='none'/>
|
||||
<s:script src="%{jqueryJs}"></s:script>
|
||||
<s:script src="%{jqueryJs}"/>
|
||||
<s:url var="bootstrapJs" value='/js/bootstrap.min.js' encode='false' includeParams='none'/>
|
||||
<s:script src="%{bootstrapJs}"></s:script>
|
||||
<s:script src="%{bootstrapJs}"/>
|
||||
<s:script type="text/javascript">
|
||||
$(function () {
|
||||
var alerts = $('ul.alert').wrap('<div />');
|
||||
@@ -82,19 +82,22 @@
|
||||
|
||||
<!-- Prettify -->
|
||||
<s:url var="prettifyCss" value='/styles/prettify.css' encode='false' includeParams='none'/>
|
||||
<s:link href="%{prettifyCss}" rel="stylesheet"></s:link>
|
||||
<s:link href="%{prettifyCss}" rel="stylesheet"/>
|
||||
<s:url var="prettifyJs" value='/js/prettify.js' encode='false' includeParams='none'/>
|
||||
<s:script src="%{prettifyJs}"></s:script>
|
||||
<s:script src="%{prettifyJs}"/>
|
||||
|
||||
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
|
||||
<!--[if lt IE 9]>
|
||||
<s:script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></s:script>
|
||||
<s:script src="http://html5shim.googlecode.com/svn/trunk/html5.js"/>
|
||||
<![endif]-->
|
||||
|
||||
<s:script>
|
||||
jQuery(document).ready(function() { prettyPrint(); } );
|
||||
</s:script>
|
||||
<decorator:head/>
|
||||
</head>
|
||||
|
||||
<body id="page-home" onload="prettyPrint();">
|
||||
<body id="page-home">
|
||||
|
||||
<nav class="navbar navbar-default navbar-fixed-top">
|
||||
<div class="container-fluid">
|
||||
@@ -239,11 +242,13 @@
|
||||
</li>
|
||||
<li><s:a value="/person/index.html">Person Manager</s:a></li>
|
||||
<li><s:a value="/skill/index.html">CRUD</s:a></li>
|
||||
<li><s:a value="/wait/index.html">Execute & Wait</s:a></li>
|
||||
<li><s:a value="/wait/index">Execute & Wait</s:a></li>
|
||||
<li><s:a value="/token/index.html">Token</s:a></li>
|
||||
<li><s:url var="url" namespace="/modelDriven" action="modelDriven"/><s:a
|
||||
href="%{url}">Model Driven</s:a></li>
|
||||
<li><s:a value="/async/index.html">Async</s:a></li>
|
||||
<li><s:a value="/dispatcher/dispatch.action">Dispatcher result - dispatch</s:a></li>
|
||||
<li><s:a value="/dispatcher/forward.action">Dispatcher result - forward</s:a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
<!--
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
-->
|
||||
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
|
||||
<%@ taglib prefix="s" uri="/struts-tags" %>
|
||||
<html>
|
||||
<head>
|
||||
<title>Struts2 Showcase - Dispatcher result Example</title>
|
||||
<s:head theme="xhtml"/>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="page-header">
|
||||
<h1>Dispatcher Result Example</h1>
|
||||
</div>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div id="dispatcher-result" class="col-md-12">
|
||||
This page is a result of "dispatching" to it from an action
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,19 +1,19 @@
|
||||
<!--
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* 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
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* 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
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
@@ -26,49 +26,46 @@
|
||||
<body>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h1>View Sources</h1>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h1>View Sources</h1>
|
||||
|
||||
<ul class="nav nav-tabs" id="codeTab">
|
||||
<li class="active"><a href="#page">Page</a></li>
|
||||
<li><a href="#config">Configuration</a></li>
|
||||
<li><a href="#java">Java Action</a></li>
|
||||
</ul>
|
||||
<ul class="nav nav-tabs" id="codeTab">
|
||||
<li class="active"><a href="#page">Page</a></li>
|
||||
<li><a href="#config">Configuration</a></li>
|
||||
<li><a href="#java">Java Action</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane active" id="page">
|
||||
<h3><s:property default="Unknown page" value="page"/></h3>
|
||||
<pre class="prettyprint lang-html linenums">
|
||||
<s:iterator value="pageLines" status="row">
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane active" id="page">
|
||||
<h3><s:property default="Unknown page" value="page"/></h3>
|
||||
<pre class="prettyprint lang-html linenums"><s:iterator value="pageLines" status="row">
|
||||
<s:property/></s:iterator>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="tab-pane" id="config">
|
||||
<h3><s:property default="Unknown configuration" value="config"/></h3>
|
||||
<pre class="prettyprint lang-xml linenums">
|
||||
<s:iterator value="configLines" status="row">
|
||||
</pre>
|
||||
</div>
|
||||
<div class="tab-pane" id="config">
|
||||
<h3><s:property default="Unknown configuration" value="config"/></h3>
|
||||
<pre class="prettyprint lang-xml linenums"><s:iterator value="configLines" status="row">
|
||||
<s:property/></s:iterator>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="tab-pane" id="java">
|
||||
<h3><s:property default="Unknown or unavailable Action class" value="className"/></h3>
|
||||
<pre class="prettyprint lang-java linenums">
|
||||
<s:iterator value="classLines" status="row">
|
||||
</pre>
|
||||
</div>
|
||||
<div class="tab-pane" id="java">
|
||||
<h3><s:property default="Unknown or unavailable Action class" value="className"/></h3>
|
||||
<pre class="prettyprint lang-java linenums"><s:iterator value="classLines" status="row">
|
||||
<s:property/></s:iterator>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<s:script>
|
||||
$('#codeTab a').click(function (e) {
|
||||
e.preventDefault();
|
||||
$(this).tab('show');
|
||||
})
|
||||
$('#codeTab a').click(function (e) {
|
||||
e.preventDefault();
|
||||
$(this).tab('show');
|
||||
})
|
||||
</s:script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
<!--
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* 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
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* 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
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
@@ -21,25 +21,26 @@
|
||||
<%@ taglib prefix="s" uri="/struts-tags" %>
|
||||
<html>
|
||||
<head>
|
||||
<title>Struts2 Showcase - Execute and Wait Examples - Complete</title>
|
||||
<title>Struts2 Showcase - Execute and Wait Examples - Complete</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="page-header">
|
||||
<h1>The process is complete</h1>
|
||||
<h1>The process is complete</h1>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-12" style="text-align: center;">
|
||||
<div class="row">
|
||||
<div class="col-md-12" style="text-align: center;">
|
||||
|
||||
<b>We have processed your request.</b>
|
||||
<p/>
|
||||
Click here to <s:url var="back" value="/wait/index.html"/><s:a href="%{back}" cssClass="btn btn-link">return</s:a>.
|
||||
<div class="panel">We have processed your request.</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<s:url var="back" value="/wait/index"/>
|
||||
Click here to <s:a href="%{back}" cssClass="btn btn-primary">return</s:a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
<!--
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
-->
|
||||
<%@ taglib prefix="s" uri="/struts-tags" %>
|
||||
<html>
|
||||
<head>
|
||||
<title>Struts2 Showcase - Execute and Wait Examples</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="page-header">
|
||||
<h1>Execute and Wait Examples</h1>
|
||||
</div>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-12" style="text-align: center;">
|
||||
|
||||
<p>
|
||||
These examples illustrate Struts build in support for execute and wait.
|
||||
<p/>
|
||||
<p>
|
||||
When you have a process that takes a long time your users can be impatient and starts to submit/click
|
||||
again.
|
||||
<br/> A good solution is to show the user a progress page (wait page) while the process takes it time.
|
||||
<p/>
|
||||
|
||||
<br/>
|
||||
<br/><a href='<s:url value="example1"/>'>Example 1 (no delay)</a>
|
||||
<br/><a href='<s:url value="example2"/>'>Example 2 (with delay)</a>
|
||||
<br/><a href='<s:url value="example3"/>'>Example 3 (with longer check delay)</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,19 +1,19 @@
|
||||
<!--
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* 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
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* 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
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
@@ -21,53 +21,33 @@
|
||||
<%@ taglib prefix="s" uri="/struts-tags" %>
|
||||
<html>
|
||||
<head>
|
||||
<title>Struts2 Showcase - Execute and Wait Examples - Wait</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="page-header">
|
||||
<h1>Execute and Wait Examples - Wait</h1>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-12" style="text-align: center;">
|
||||
|
||||
<p class="well">
|
||||
We are processing your request. Please wait.
|
||||
</p>
|
||||
|
||||
<div class="progress progress-striped active">
|
||||
<div class="bar" style="width: 50%;"></div>
|
||||
</div>
|
||||
|
||||
<p/>
|
||||
You can click this link to <a href="<s:url includeParams="all"/>">refresh</a>.
|
||||
|
||||
<b>We have processed your request.</b>
|
||||
<p/>
|
||||
Click here to <s:url var="back" value="/wait/index.html"/><s:a href="%{back}" cssClass="btn btn-link">return</s:a>.
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<%@ taglib prefix="s" uri="/struts-tags" %>
|
||||
<html>
|
||||
<head>
|
||||
<title>Struts2 Showcase - Execute and Wait Examples - Wait</title>
|
||||
<meta http-equiv="refresh" content="5;url=<s:url includeParams="all"/>"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p style="border: 1px solid silver; padding: 5px; background: #ffd; text-align: center;">
|
||||
We are processing your request. Please wait.
|
||||
</p>
|
||||
<div class="page-header">
|
||||
<h1>Execute and Wait Examples - Wait</h1>
|
||||
</div>
|
||||
|
||||
<p/>
|
||||
You can click this link to <a href="<s:url includeParams="all"/>">refresh</a>.
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-12" style="text-align: center;">
|
||||
|
||||
<p class="well">
|
||||
We are processing your request. Please wait.
|
||||
</p>
|
||||
|
||||
<div class="progress progress-striped active">
|
||||
<div class="bar progress-bar progress-bar-success" style="width: 50%;"></div>
|
||||
</div>
|
||||
|
||||
<div class="panel">
|
||||
You can click this link to <a href="<s:url includeParams="all"/>">refresh</a>.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
/*
|
||||
* 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
|
||||
@@ -16,20 +17,16 @@
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
-->
|
||||
<web-app id="starter" version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
|
||||
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
|
||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
|
||||
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
|
||||
version="3.1">
|
||||
|
||||
<display-name>Struts Showcase Application</display-name>
|
||||
|
||||
<context-param>
|
||||
<param-name>org.apache.tiles.definition.DefinitionsFactory.DEFINITIONS_CONFIG</param-name>
|
||||
<param-value>
|
||||
/WEB-INF/tiles.xml
|
||||
</param-value>
|
||||
</context-param>
|
||||
|
||||
<filter>
|
||||
<filter-name>async</filter-name>
|
||||
<filter-class>org.apache.struts2.showcase.async.AsyncFilter</filter-class>
|
||||
@@ -39,18 +36,20 @@
|
||||
<filter>
|
||||
<filter-name>struts-prepare</filter-name>
|
||||
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareFilter</filter-class>
|
||||
<async-supported>true</async-supported>
|
||||
</filter>
|
||||
|
||||
<filter>
|
||||
<filter-name>struts-execute</filter-name>
|
||||
<filter-class>org.apache.struts2.dispatcher.filter.StrutsExecuteFilter</filter-class>
|
||||
<async-supported>true</async-supported>
|
||||
</filter>
|
||||
|
||||
|
||||
<filter>
|
||||
<filter-name>sitemesh</filter-name>
|
||||
<filter-class>com.opensymphony.sitemesh.webapp.SiteMeshFilter</filter-class>
|
||||
</filter>
|
||||
<filter>
|
||||
<filter-name>sitemesh</filter-name>
|
||||
<filter-class>com.opensymphony.sitemesh.webapp.SiteMeshFilter</filter-class>
|
||||
<async-supported>true</async-supported>
|
||||
</filter>
|
||||
|
||||
<filter-mapping>
|
||||
<filter-name>async</filter-name>
|
||||
@@ -60,16 +59,22 @@
|
||||
<filter-mapping>
|
||||
<filter-name>struts-prepare</filter-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
<dispatcher>FORWARD</dispatcher>
|
||||
<dispatcher>REQUEST</dispatcher>
|
||||
</filter-mapping>
|
||||
|
||||
<filter-mapping>
|
||||
<filter-name>sitemesh</filter-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
<dispatcher>FORWARD</dispatcher>
|
||||
<dispatcher>REQUEST</dispatcher>
|
||||
</filter-mapping>
|
||||
|
||||
<filter-mapping>
|
||||
<filter-name>struts-execute</filter-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
<dispatcher>FORWARD</dispatcher>
|
||||
<dispatcher>REQUEST</dispatcher>
|
||||
</filter-mapping>
|
||||
|
||||
<listener>
|
||||
@@ -81,18 +86,18 @@
|
||||
org.apache.struts2.tiles.StrutsTilesListener
|
||||
</listener-class>
|
||||
</listener>
|
||||
|
||||
|
||||
<!-- Chat Example in Showcase -->
|
||||
<listener>
|
||||
<listener-class>
|
||||
org.apache.struts2.showcase.chat.ChatSessionListener
|
||||
</listener-class>
|
||||
<listener-class>
|
||||
org.apache.struts2.showcase.chat.ChatSessionListener
|
||||
</listener-class>
|
||||
</listener>
|
||||
|
||||
<listener>
|
||||
<listener-class>org.apache.struts2.dispatcher.listener.StrutsListener</listener-class>
|
||||
</listener>
|
||||
|
||||
|
||||
<!-- SNIPPET START: dwr -->
|
||||
|
||||
<servlet>
|
||||
@@ -103,13 +108,20 @@
|
||||
<param-value>true</param-value>
|
||||
</init-param>
|
||||
</servlet>
|
||||
<servlet>
|
||||
<servlet-name>JspSupportServlet</servlet-name>
|
||||
<servlet-class>org.apache.struts2.views.JspSupportServlet</servlet-class>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
<servlet>
|
||||
<servlet-name>JspSupportServlet</servlet-name>
|
||||
<servlet-class>org.apache.struts2.views.JspSupportServlet</servlet-class>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
|
||||
<!-- Sitemesh Freemarker and Velocity Decorator Servlets. Shares configuration with Struts.-->
|
||||
<servlet>
|
||||
<servlet-name>strutsServlet</servlet-name>
|
||||
<servlet-class>org.apache.struts2.dispatcher.servlet.StrutsServlet</servlet-class>
|
||||
<load-on-startup>2</load-on-startup>
|
||||
<async-supported>true</async-supported>
|
||||
</servlet>
|
||||
|
||||
<!-- Sitemesh Freemarker and Velocity Decorator Servlets. Shares configuration with Struts.-->
|
||||
<servlet>
|
||||
<servlet-name>sitemesh-freemarker</servlet-name>
|
||||
<servlet-class>org.apache.struts2.sitemesh.FreemarkerDecoratorServlet</servlet-class>
|
||||
@@ -117,7 +129,7 @@
|
||||
<param-name>default_encoding</param-name>
|
||||
<param-value>UTF-8</param-value>
|
||||
</init-param>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
<load-on-startup>3</load-on-startup>
|
||||
</servlet>
|
||||
|
||||
<servlet>
|
||||
@@ -127,14 +139,7 @@
|
||||
<param-name>default_encoding</param-name>
|
||||
<param-value>UTF-8</param-value>
|
||||
</init-param>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>strutsServlet</servlet-name>
|
||||
<servlet-class>org.apache.struts2.dispatcher.servlet.StrutsServlet</servlet-class>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
<async-supported>true</async-supported>
|
||||
<load-on-startup>4</load-on-startup>
|
||||
</servlet>
|
||||
|
||||
<servlet-mapping>
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
<!--
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>Struts2 Showcase - Execute and Wait Examples</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="page-header">
|
||||
<h1>Execute and Wait Examples</h1>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-12" style="text-align: center;">
|
||||
|
||||
<p>
|
||||
These examples illustrate Struts build in support for execute and wait.
|
||||
<p/>
|
||||
<p>
|
||||
When you have a process that takes a long time your users can be impatient and starts to submit/click again.
|
||||
<br/> A good solution is to show the user a progress page (wait page) while the process takes it time.
|
||||
<p/>
|
||||
|
||||
<br/>
|
||||
<br/><a href="example1.action">Example 1 (no delay)</a>
|
||||
<br/><a href="example2.action">Example 2 (with delay)</a>
|
||||
<br/><a href="example3.action">Example 3 (with longer check delay)</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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 it.org.apache.struts2.showcase;
|
||||
|
||||
import com.gargoylesoftware.htmlunit.WebClient;
|
||||
import com.gargoylesoftware.htmlunit.html.DomElement;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlPage;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class DispatcherResultTest {
|
||||
|
||||
@Test
|
||||
public void testDispatchingToJSP() throws Exception {
|
||||
try (final WebClient webClient = new WebClient()) {
|
||||
final HtmlPage page = webClient.getPage(ParameterUtils.getBaseUrl() + "/dispatcher/dispatch.action");
|
||||
|
||||
DomElement div = page.getElementById("dispatcher-result");
|
||||
|
||||
Assert.assertEquals("This page is a result of \"dispatching\" to it from an action", div.asNormalizedText());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDispatchingToAction() throws Exception {
|
||||
try (final WebClient webClient = new WebClient()) {
|
||||
webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);
|
||||
final HtmlPage page = webClient.getPage(ParameterUtils.getBaseUrl() + "/dispatcher/forward.action");
|
||||
|
||||
//DomElement div = page.getElementById("dispatcher-result");
|
||||
//Assert.assertEquals("This page is a result of \"dispatching\" to it from an action", div.asNormalizedText());
|
||||
// support for forwarding to another action is broken on StrutsPrepareFilter/StrutsExecuteFilter
|
||||
// it only works in StrutsPrepareAndExecuteFilter
|
||||
// this will be fixed in Struts 6.1.x
|
||||
|
||||
Assert.assertEquals(404, page.getWebResponse().getStatusCode());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
# Struts 2 Assemblies
|
||||
This module is used to prepare ZIP archives with different set of JARs, like code source, Javadocs, etc.
|
||||
It's a part of the release process, it shouldn't be used directly by users.
|
||||
+1
-1
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-parent</artifactId>
|
||||
<version>6.0.0</version>
|
||||
<version>6.1.2</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-assembly</artifactId>
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
<include>org.apache.struts:struts2-core</include>
|
||||
<include>org.freemarker:freemarker</include>
|
||||
<include>org.apache.commons:commons-lang3</include>
|
||||
<include>org.apache.commons:commons-text</include>
|
||||
<include>org.apache.logging.log4j:log4j-api</include>
|
||||
<include>ognl:ognl</include>
|
||||
<include>commons-fileupload:commons-fileupload</include>
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
# Struts 2 BOM
|
||||
This is a Bill-Of-Materials to be used with Maven based project. It allows to import all the Struts 2
|
||||
dependencies at once and used them in your project where needed.
|
||||
|
||||
## Installation
|
||||
You must add a proper import statement into your `pom.xml` as presented below:
|
||||
|
||||
```xml
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-bom</artifactId>
|
||||
<version>${struts2.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
```
|
||||
+13
-3
@@ -29,7 +29,7 @@
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-bom</artifactId>
|
||||
<version>6.0.0</version>
|
||||
<version>6.1.2</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>Struts 2 Bill of Materials</name>
|
||||
@@ -44,7 +44,7 @@
|
||||
</licenses>
|
||||
|
||||
<properties>
|
||||
<struts-version.version>6.0.0</struts-version.version>
|
||||
<struts-version.version>6.1.2</struts-version.version>
|
||||
<maven.site.skip>true</maven.site.skip>
|
||||
<maven.site.deploy.skip>true</maven.site.deploy.skip>
|
||||
</properties>
|
||||
@@ -56,6 +56,11 @@
|
||||
<artifactId>struts2-core</artifactId>
|
||||
<version>${struts-version.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-async-plugin</artifactId>
|
||||
<version>${struts-version.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-bean-validation-plugin</artifactId>
|
||||
@@ -171,11 +176,16 @@
|
||||
<artifactId>struts2-tiles-plugin</artifactId>
|
||||
<version>${struts-version.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-velocity-plugin</artifactId>
|
||||
<version>${struts-version.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<scm>
|
||||
<tag>STRUTS_6_0_0</tag>
|
||||
<tag>STRUTS_6_1_2</tag>
|
||||
<connection>scm:git:https://gitbox.apache.org/repos/asf/struts.git</connection>
|
||||
<developerConnection>scm:git:https://gitbox.apache.org/repos/asf/struts.git</developerConnection>
|
||||
<url>https://github.com/apache/struts/</url>
|
||||
|
||||
@@ -24,12 +24,12 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-osgi-bundles</artifactId>
|
||||
<version>6.0.0</version>
|
||||
<version>6.1.2</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-osgi-admin-bundle</artifactId>
|
||||
<packaging>bundle</packaging>
|
||||
<name>DEPRECATED: Struts 2 OSGi Admin Bundle - since 2.6</name>
|
||||
<name>DEPRECATED: Struts 2 OSGi Admin Bundle - since 6.0.0</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
|
||||
@@ -22,13 +22,13 @@
|
||||
|
||||
<!DOCTYPE struts PUBLIC
|
||||
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
|
||||
"http://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
"https://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
|
||||
<struts>
|
||||
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
|
||||
<package name="bundle-admin" namespace="/osgi/admin" extends="osgi-default" strict-method-invocation="true">
|
||||
<default-action-ref name="bundles" />
|
||||
|
||||
|
||||
<action name="bundle_*!*" class="org.apache.struts2.osgi.admin.actions.BundlesAction" method="{2}">
|
||||
<param name="id">{1}</param>
|
||||
<result type="freemarker">viewBundle.ftl</result>
|
||||
|
||||
@@ -24,12 +24,12 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-osgi-bundles</artifactId>
|
||||
<version>6.0.0</version>
|
||||
<version>6.1.2</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-osgi-demo-bundle</artifactId>
|
||||
<packaging>bundle</packaging>
|
||||
<name>DEPRECATED: Struts 2 OSGi Demo Bundle - since 2.6</name>
|
||||
<name>DEPRECATED: Struts 2 OSGi Demo Bundle - since 6.0.0</name>
|
||||
|
||||
<dependencies>
|
||||
|
||||
|
||||
@@ -21,11 +21,11 @@
|
||||
-->
|
||||
<!DOCTYPE struts PUBLIC
|
||||
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
|
||||
"http://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
"https://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
|
||||
<struts>
|
||||
<!-- Set some Struts 2 constants relevant to the OSGi Plugin.
|
||||
Note: The constant definitions specified here (within the demo bundle) may also need to be
|
||||
<!-- Set some Struts 2 constants relevant to the OSGi Plugin.
|
||||
Note: The constant definitions specified here (within the demo bundle) may also need to be
|
||||
duplicated in the struts.xml configuration of the outer project that packages the demo
|
||||
bundle JAR file within it.
|
||||
-->
|
||||
@@ -52,4 +52,4 @@
|
||||
</action>
|
||||
|
||||
</package>
|
||||
</struts>
|
||||
</struts>
|
||||
|
||||
+2
-2
@@ -24,12 +24,12 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-parent</artifactId>
|
||||
<version>6.0.0</version>
|
||||
<version>6.1.2</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-osgi-bundles</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<name>DEPRECATED: Struts 2 OSGi Bundles - since 2.6</name>
|
||||
<name>DEPRECATED: Struts 2 OSGi Bundles - since 6.0.0</name>
|
||||
|
||||
<modules>
|
||||
<module>admin</module>
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
# Struts 2 Core
|
||||
This is a core of the Apache Struts framework and all other modules depend on it.
|
||||
It requires Java 8 at minimum and a Servlet container supporting Java Servlet API 3.1 at least.
|
||||
|
||||
## Installation
|
||||
Just drop this plugin into `WEB-INF/lib` folder or add it as Maven dependency
|
||||
+4
-7
@@ -24,14 +24,14 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-parent</artifactId>
|
||||
<version>6.0.0</version>
|
||||
<version>6.1.2</version>
|
||||
</parent>
|
||||
<artifactId>struts2-core</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Struts 2 Core</name>
|
||||
|
||||
<properties>
|
||||
<tlib.version>2.6</tlib.version>
|
||||
<tlib.version>6.0</tlib.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<argLine>@{argLine}</argLine>
|
||||
<properties>
|
||||
<property>
|
||||
<name>maven.testng.output.dir</name>
|
||||
@@ -54,9 +55,6 @@
|
||||
<element>${project.build.testOutputDirectory}/xwork - jar.jar</element>
|
||||
<element>${project.build.testOutputDirectory}/xwork - zip.zip</element>
|
||||
</additionalClasspathElements>
|
||||
<includes>
|
||||
<include>**/*Test.java</include>
|
||||
</includes>
|
||||
<excludes>
|
||||
<exclude>**/XWorkTestCase.java</exclude>
|
||||
<exclude>**/TestBean.java</exclude>
|
||||
@@ -339,8 +337,7 @@
|
||||
<dependency>
|
||||
<groupId>org.testng</groupId>
|
||||
<artifactId>testng</artifactId>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- SLF4J support -->
|
||||
|
||||
@@ -24,7 +24,7 @@ import java.util.concurrent.Callable;
|
||||
* Adds support for invoke async actions. This allows us to support action methods that return {@link Callable}
|
||||
* as well as invoking them in separate not-container thread then executing the result in another container thread.
|
||||
*
|
||||
* @since 2.6
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public interface AsyncManager {
|
||||
boolean hasAsyncActionResult();
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.opensymphony.xwork2.config.entities.InterceptorMapping;
|
||||
import com.opensymphony.xwork2.config.entities.ResultConfig;
|
||||
import com.opensymphony.xwork2.inject.Container;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import com.opensymphony.xwork2.interceptor.ConditionalInterceptor;
|
||||
import com.opensymphony.xwork2.interceptor.Interceptor;
|
||||
import com.opensymphony.xwork2.interceptor.PreResultListener;
|
||||
import com.opensymphony.xwork2.interceptor.WithLazyParams;
|
||||
@@ -73,7 +74,7 @@ public class DefaultActionInvocation implements ActionInvocation {
|
||||
protected UnknownHandlerManager unknownHandlerManager;
|
||||
protected OgnlUtil ognlUtil;
|
||||
protected AsyncManager asyncManager;
|
||||
protected Callable asyncAction;
|
||||
protected Callable<?> asyncAction;
|
||||
protected WithLazyParams.LazyParamInjector lazyParamInjector;
|
||||
|
||||
public DefaultActionInvocation(final Map<String, Object> extraContext, final boolean pushAction) {
|
||||
@@ -101,7 +102,7 @@ public class DefaultActionInvocation implements ActionInvocation {
|
||||
this.container = cont;
|
||||
}
|
||||
|
||||
@Inject(required=false)
|
||||
@Inject(required = false)
|
||||
public void setActionEventListener(ActionEventListener listener) {
|
||||
this.actionEventListener = listener;
|
||||
}
|
||||
@@ -111,7 +112,7 @@ public class DefaultActionInvocation implements ActionInvocation {
|
||||
this.ognlUtil = ognlUtil;
|
||||
}
|
||||
|
||||
@Inject(required=false)
|
||||
@Inject(required = false)
|
||||
public void setAsyncManager(AsyncManager asyncManager) {
|
||||
this.asyncManager = asyncManager;
|
||||
}
|
||||
@@ -214,7 +215,7 @@ public class DefaultActionInvocation implements ActionInvocation {
|
||||
} catch (NullPointerException e) {
|
||||
LOG.debug("Got NPE trying to read result configuration for resultCode [{}]", resultCode);
|
||||
}
|
||||
|
||||
|
||||
if (resultConfig == null) {
|
||||
// If no result is found for the given resultCode, try to get a wildcard '*' match.
|
||||
resultConfig = results.get("*");
|
||||
@@ -248,7 +249,12 @@ public class DefaultActionInvocation implements ActionInvocation {
|
||||
if (interceptor instanceof WithLazyParams) {
|
||||
interceptor = lazyParamInjector.injectParams(interceptor, interceptorMapping.getParams(), invocationContext);
|
||||
}
|
||||
resultCode = interceptor.intercept(DefaultActionInvocation.this);
|
||||
if (interceptor instanceof ConditionalInterceptor) {
|
||||
resultCode = executeConditional((ConditionalInterceptor) interceptor);
|
||||
} else {
|
||||
LOG.debug("Executing normal interceptor: {}", interceptorMapping.getName());
|
||||
resultCode = interceptor.intercept(this);
|
||||
}
|
||||
} else {
|
||||
resultCode = invokeActionOnly();
|
||||
}
|
||||
@@ -268,9 +274,7 @@ public class DefaultActionInvocation implements ActionInvocation {
|
||||
if (preResultListeners != null) {
|
||||
LOG.trace("Executing PreResultListeners for result [{}]", result);
|
||||
|
||||
for (Object preResultListener : preResultListeners) {
|
||||
PreResultListener listener = (PreResultListener) preResultListener;
|
||||
|
||||
for (PreResultListener listener : preResultListeners) {
|
||||
listener.beforeResult(this, resultCode);
|
||||
}
|
||||
}
|
||||
@@ -289,6 +293,16 @@ public class DefaultActionInvocation implements ActionInvocation {
|
||||
return resultCode;
|
||||
}
|
||||
|
||||
protected String executeConditional(ConditionalInterceptor conditionalInterceptor) throws Exception {
|
||||
if (conditionalInterceptor.shouldIntercept(this)) {
|
||||
LOG.debug("Executing conditional interceptor: {}", conditionalInterceptor.getClass().getSimpleName());
|
||||
return conditionalInterceptor.intercept(this);
|
||||
} else {
|
||||
LOG.debug("Interceptor: {} is disabled, skipping to next", conditionalInterceptor.getClass().getSimpleName());
|
||||
return this.invoke();
|
||||
}
|
||||
}
|
||||
|
||||
public String invokeActionOnly() throws Exception {
|
||||
return invokeAction(getAction(), proxy.getConfig());
|
||||
}
|
||||
@@ -314,7 +328,7 @@ public class DefaultActionInvocation implements ActionInvocation {
|
||||
gripe = "Unable to instantiate Action, " + proxy.getConfig().getClassName() + ", defined for '" + proxy.getActionName() + "' in namespace '" + proxy.getNamespace() + "'";
|
||||
}
|
||||
|
||||
gripe += (((" -- " + e.getMessage()) != null) ? e.getMessage() : " [no message in exception]");
|
||||
gripe += e.getMessage();
|
||||
throw new StrutsException(gripe, e, proxy.getConfig());
|
||||
}
|
||||
|
||||
@@ -363,7 +377,7 @@ public class DefaultActionInvocation implements ActionInvocation {
|
||||
result.execute(this);
|
||||
} else if (resultCode != null && !Action.NONE.equals(resultCode)) {
|
||||
throw new ConfigurationException("No result defined for action " + getAction().getClass().getName()
|
||||
+ " and result " + getResultCode(), proxy.getConfig());
|
||||
+ " and result " + getResultCode(), proxy.getConfig());
|
||||
} else {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("No result returned for action {} at {}", getAction().getClass().getName(), proxy.getConfig().getLocation());
|
||||
@@ -464,6 +478,7 @@ public class DefaultActionInvocation implements ActionInvocation {
|
||||
|
||||
/**
|
||||
* Save the result to be used later.
|
||||
*
|
||||
* @param actionConfig current ActionConfig
|
||||
* @param methodResult the result of the action.
|
||||
* @return the result code to process.
|
||||
@@ -476,7 +491,7 @@ public class DefaultActionInvocation implements ActionInvocation {
|
||||
container.inject(explicitResult);
|
||||
return null;
|
||||
} else if (methodResult instanceof Callable) {
|
||||
asyncAction = (Callable) methodResult;
|
||||
asyncAction = (Callable<?>) methodResult;
|
||||
return null;
|
||||
} else {
|
||||
return (String) methodResult;
|
||||
|
||||
@@ -34,22 +34,22 @@ import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Base JUnit TestCase to extend for XWork specific JUnit tests. Uses
|
||||
* Base JUnit TestCase to extend for XWork specific JUnit tests. Uses
|
||||
* the generic test setup for logic.
|
||||
*
|
||||
* @author plightbo
|
||||
*/
|
||||
public abstract class XWorkTestCase extends TestCase {
|
||||
|
||||
|
||||
protected ConfigurationManager configurationManager;
|
||||
protected Configuration configuration;
|
||||
protected Container container;
|
||||
protected ActionProxyFactory actionProxyFactory;
|
||||
|
||||
|
||||
public XWorkTestCase() {
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
configurationManager = XWorkTestCaseHelper.setUp();
|
||||
@@ -57,7 +57,7 @@ public abstract class XWorkTestCase extends TestCase {
|
||||
container = configuration.getContainer();
|
||||
actionProxyFactory = container.getInstance(ActionProxyFactory.class);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
XWorkTestCaseHelper.tearDown(configurationManager);
|
||||
@@ -66,34 +66,33 @@ public abstract class XWorkTestCase extends TestCase {
|
||||
container = null;
|
||||
actionProxyFactory = null;
|
||||
}
|
||||
|
||||
|
||||
protected void loadConfigurationProviders(ConfigurationProvider... providers) {
|
||||
configurationManager = XWorkTestCaseHelper.loadConfigurationProviders(configurationManager, providers);
|
||||
configuration = configurationManager.getConfiguration();
|
||||
container = configuration.getContainer();
|
||||
actionProxyFactory = container.getInstance(ActionProxyFactory.class);
|
||||
}
|
||||
|
||||
protected void loadButAdd(final Class<?> type, final Object impl) {
|
||||
|
||||
protected <T> void loadButAdd(final Class<T> type, final T impl) {
|
||||
loadButAdd(type, Container.DEFAULT_NAME, impl);
|
||||
}
|
||||
|
||||
protected void loadButAdd(final Class<?> type, final String name, final Object impl) {
|
||||
|
||||
protected <T> void loadButAdd(final Class<T> type, final String name, final T impl) {
|
||||
loadConfigurationProviders(new StubConfigurationProvider() {
|
||||
@Override
|
||||
public void register(ContainerBuilder builder,
|
||||
LocatableProperties props) throws ConfigurationException {
|
||||
public void register(ContainerBuilder builder, LocatableProperties props) throws ConfigurationException {
|
||||
if (impl instanceof String || ClassUtils.isPrimitiveOrWrapper(impl.getClass())) {
|
||||
props.setProperty(name, "" + impl);
|
||||
} else {
|
||||
builder.factory(type, name, new Factory() {
|
||||
public Object create(Context context) throws Exception {
|
||||
builder.factory(type, name, new Factory<T>() {
|
||||
public T create(Context context) throws Exception {
|
||||
return impl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class type() {
|
||||
return impl.getClass();
|
||||
public Class<T> type() {
|
||||
return (Class<T>) impl.getClass();
|
||||
}
|
||||
}, Scope.SINGLETON);
|
||||
}
|
||||
|
||||
@@ -20,26 +20,18 @@ package com.opensymphony.xwork2.config.entities;
|
||||
|
||||
import com.opensymphony.xwork2.util.location.Located;
|
||||
import com.opensymphony.xwork2.util.location.Location;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
/**
|
||||
* Configuration for Package.
|
||||
*
|
||||
* <p>
|
||||
* In the xml configuration file this is defined as the <code>package</code> tag.
|
||||
* </p>
|
||||
*
|
||||
* @author Rainer Hermanns
|
||||
* @version $Revision$
|
||||
*/
|
||||
public class PackageConfig extends Located implements Comparable, Serializable, InterceptorLocator {
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(PackageConfig.class);
|
||||
public class PackageConfig extends Located implements Comparable<PackageConfig>, Serializable, InterceptorLocator {
|
||||
|
||||
protected Map<String, ActionConfig> actionConfigs;
|
||||
protected Map<String, ResultConfig> globalResultConfigs;
|
||||
@@ -422,8 +414,7 @@ public class PackageConfig extends Located implements Comparable, Serializable,
|
||||
return "PackageConfig: [" + name + "] for namespace [" + namespace + "] with parents [" + parents + "]";
|
||||
}
|
||||
|
||||
public int compareTo(Object o) {
|
||||
PackageConfig other = (PackageConfig) o;
|
||||
public int compareTo(PackageConfig other) {
|
||||
String full = namespace + "!" + name;
|
||||
String otherFull = other.namespace + "!" + other.name;
|
||||
|
||||
@@ -443,7 +434,6 @@ public class PackageConfig extends Located implements Comparable, Serializable,
|
||||
public static class Builder implements InterceptorLocator {
|
||||
|
||||
protected PackageConfig target;
|
||||
private boolean strictDMI = true;
|
||||
|
||||
public Builder(String name) {
|
||||
target = new PackageConfig(name);
|
||||
|
||||
@@ -298,8 +298,8 @@ public class DefaultConfiguration implements Configuration {
|
||||
|
||||
builder.factory(ObjectTypeDeterminer.class, DefaultObjectTypeDeterminer.class, Scope.SINGLETON);
|
||||
builder.factory(PropertyAccessor.class, CompoundRoot.class.getName(), CompoundRootAccessor.class, Scope.SINGLETON);
|
||||
builder.factory(ExpressionCacheFactory.class, "defaultOgnlExpressionCacheFactory", DefaultOgnlExpressionCacheFactory.class, Scope.SINGLETON);
|
||||
builder.factory(BeanInfoCacheFactory.class, "defaultOgnlBeanInfoCacheFactory", DefaultOgnlBeanInfoCacheFactory.class, Scope.SINGLETON);
|
||||
builder.factory(ExpressionCacheFactory.class, DefaultOgnlExpressionCacheFactory.class, Scope.SINGLETON);
|
||||
builder.factory(BeanInfoCacheFactory.class, DefaultOgnlBeanInfoCacheFactory.class, Scope.SINGLETON);
|
||||
builder.factory(OgnlUtil.class, Scope.SINGLETON);
|
||||
|
||||
builder.factory(ValueSubstitutor.class, EnvsValueSubstitutor.class, Scope.SINGLETON);
|
||||
|
||||
+99
-92
@@ -21,26 +21,16 @@ package com.opensymphony.xwork2.config.providers;
|
||||
import com.opensymphony.xwork2.ActionProxyFactory;
|
||||
import com.opensymphony.xwork2.DefaultActionProxyFactory;
|
||||
import com.opensymphony.xwork2.DefaultLocaleProviderFactory;
|
||||
import com.opensymphony.xwork2.LocaleProviderFactory;
|
||||
import com.opensymphony.xwork2.StrutsTextProviderFactory;
|
||||
import com.opensymphony.xwork2.TextProviderFactory;
|
||||
import com.opensymphony.xwork2.factory.DefaultUnknownHandlerFactory;
|
||||
import com.opensymphony.xwork2.factory.UnknownHandlerFactory;
|
||||
import com.opensymphony.xwork2.ognl.BeanInfoCacheFactory;
|
||||
import com.opensymphony.xwork2.ognl.ExpressionCacheFactory;
|
||||
import com.opensymphony.xwork2.ognl.accessor.HttpParametersPropertyAccessor;
|
||||
import com.opensymphony.xwork2.ognl.accessor.ParameterPropertyAccessor;
|
||||
import com.opensymphony.xwork2.security.AcceptedPatternsChecker;
|
||||
import com.opensymphony.xwork2.security.DefaultAcceptedPatternsChecker;
|
||||
import com.opensymphony.xwork2.security.DefaultExcludedPatternsChecker;
|
||||
import com.opensymphony.xwork2.DefaultTextProvider;
|
||||
import com.opensymphony.xwork2.DefaultUnknownHandlerManager;
|
||||
import com.opensymphony.xwork2.security.DefaultNotExcludedAcceptedPatternsChecker;
|
||||
import com.opensymphony.xwork2.security.ExcludedPatternsChecker;
|
||||
import com.opensymphony.xwork2.FileManager;
|
||||
import com.opensymphony.xwork2.FileManagerFactory;
|
||||
import com.opensymphony.xwork2.LocaleProviderFactory;
|
||||
import com.opensymphony.xwork2.LocalizedTextProvider;
|
||||
import com.opensymphony.xwork2.ObjectFactory;
|
||||
import com.opensymphony.xwork2.StrutsTextProviderFactory;
|
||||
import com.opensymphony.xwork2.TextProvider;
|
||||
import com.opensymphony.xwork2.TextProviderFactory;
|
||||
import com.opensymphony.xwork2.UnknownHandlerManager;
|
||||
import com.opensymphony.xwork2.config.Configuration;
|
||||
import com.opensymphony.xwork2.config.ConfigurationException;
|
||||
@@ -57,14 +47,7 @@ import com.opensymphony.xwork2.conversion.impl.CollectionConverter;
|
||||
import com.opensymphony.xwork2.conversion.impl.DateConverter;
|
||||
import com.opensymphony.xwork2.conversion.impl.DefaultConversionAnnotationProcessor;
|
||||
import com.opensymphony.xwork2.conversion.impl.DefaultConversionFileProcessor;
|
||||
import com.opensymphony.xwork2.security.NotExcludedAcceptedPatternsChecker;
|
||||
import org.apache.struts2.components.date.DateFormatter;
|
||||
import org.apache.struts2.components.date.DateTimeFormatterAdapter;
|
||||
import org.apache.struts2.components.date.SimpleDateFormatAdapter;
|
||||
import org.apache.struts2.conversion.StrutsConversionPropertiesProcessor;
|
||||
import com.opensymphony.xwork2.conversion.impl.DefaultObjectTypeDeterminer;
|
||||
import org.apache.struts2.conversion.StrutsTypeConverterCreator;
|
||||
import org.apache.struts2.conversion.StrutsTypeConverterHolder;
|
||||
import com.opensymphony.xwork2.conversion.impl.InstantiatingNullHandler;
|
||||
import com.opensymphony.xwork2.conversion.impl.NumberConverter;
|
||||
import com.opensymphony.xwork2.conversion.impl.StringConverter;
|
||||
@@ -73,34 +56,45 @@ import com.opensymphony.xwork2.conversion.impl.XWorkConverter;
|
||||
import com.opensymphony.xwork2.factory.ActionFactory;
|
||||
import com.opensymphony.xwork2.factory.ConverterFactory;
|
||||
import com.opensymphony.xwork2.factory.DefaultActionFactory;
|
||||
import com.opensymphony.xwork2.factory.StrutsConverterFactory;
|
||||
import com.opensymphony.xwork2.factory.DefaultInterceptorFactory;
|
||||
import com.opensymphony.xwork2.factory.DefaultResultFactory;
|
||||
import com.opensymphony.xwork2.factory.DefaultUnknownHandlerFactory;
|
||||
import com.opensymphony.xwork2.factory.InterceptorFactory;
|
||||
import com.opensymphony.xwork2.factory.ResultFactory;
|
||||
import com.opensymphony.xwork2.factory.StrutsConverterFactory;
|
||||
import com.opensymphony.xwork2.factory.UnknownHandlerFactory;
|
||||
import com.opensymphony.xwork2.inject.ContainerBuilder;
|
||||
import com.opensymphony.xwork2.inject.Scope;
|
||||
import com.opensymphony.xwork2.ognl.BeanInfoCacheFactory;
|
||||
import com.opensymphony.xwork2.ognl.DefaultOgnlBeanInfoCacheFactory;
|
||||
import com.opensymphony.xwork2.ognl.DefaultOgnlExpressionCacheFactory;
|
||||
import com.opensymphony.xwork2.ognl.ExpressionCacheFactory;
|
||||
import com.opensymphony.xwork2.ognl.ObjectProxy;
|
||||
import com.opensymphony.xwork2.ognl.OgnlReflectionContextFactory;
|
||||
import com.opensymphony.xwork2.ognl.OgnlReflectionProvider;
|
||||
import com.opensymphony.xwork2.ognl.OgnlUtil;
|
||||
import com.opensymphony.xwork2.ognl.OgnlValueStackFactory;
|
||||
import com.opensymphony.xwork2.ognl.accessor.CompoundRootAccessor;
|
||||
import com.opensymphony.xwork2.ognl.accessor.HttpParametersPropertyAccessor;
|
||||
import com.opensymphony.xwork2.ognl.accessor.ObjectAccessor;
|
||||
import com.opensymphony.xwork2.ognl.accessor.ObjectProxyPropertyAccessor;
|
||||
import com.opensymphony.xwork2.ognl.accessor.ParameterPropertyAccessor;
|
||||
import com.opensymphony.xwork2.ognl.accessor.XWorkCollectionPropertyAccessor;
|
||||
import com.opensymphony.xwork2.ognl.accessor.XWorkEnumerationAccessor;
|
||||
import com.opensymphony.xwork2.ognl.accessor.XWorkIteratorPropertyAccessor;
|
||||
import com.opensymphony.xwork2.ognl.accessor.XWorkListPropertyAccessor;
|
||||
import com.opensymphony.xwork2.ognl.accessor.XWorkMapPropertyAccessor;
|
||||
import com.opensymphony.xwork2.ognl.accessor.XWorkMethodAccessor;
|
||||
import com.opensymphony.xwork2.security.AcceptedPatternsChecker;
|
||||
import com.opensymphony.xwork2.security.DefaultAcceptedPatternsChecker;
|
||||
import com.opensymphony.xwork2.security.DefaultExcludedPatternsChecker;
|
||||
import com.opensymphony.xwork2.security.DefaultNotExcludedAcceptedPatternsChecker;
|
||||
import com.opensymphony.xwork2.security.ExcludedPatternsChecker;
|
||||
import com.opensymphony.xwork2.security.NotExcludedAcceptedPatternsChecker;
|
||||
import com.opensymphony.xwork2.util.CompoundRoot;
|
||||
import com.opensymphony.xwork2.LocalizedTextProvider;
|
||||
import com.opensymphony.xwork2.ognl.DefaultOgnlBeanInfoCacheFactory;
|
||||
import com.opensymphony.xwork2.ognl.DefaultOgnlExpressionCacheFactory;
|
||||
import com.opensymphony.xwork2.util.StrutsLocalizedTextProvider;
|
||||
import com.opensymphony.xwork2.util.OgnlTextParser;
|
||||
import com.opensymphony.xwork2.util.PatternMatcher;
|
||||
import com.opensymphony.xwork2.util.StrutsLocalizedTextProvider;
|
||||
import com.opensymphony.xwork2.util.TextParser;
|
||||
import com.opensymphony.xwork2.util.ValueStackFactory;
|
||||
import com.opensymphony.xwork2.util.WildcardHelper;
|
||||
@@ -119,8 +113,19 @@ import com.opensymphony.xwork2.validator.ValidatorFileParser;
|
||||
import ognl.MethodAccessor;
|
||||
import ognl.PropertyAccessor;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
import org.apache.struts2.conversion.StrutsConversionPropertiesProcessor;
|
||||
import org.apache.struts2.conversion.StrutsTypeConverterCreator;
|
||||
import org.apache.struts2.conversion.StrutsTypeConverterHolder;
|
||||
import org.apache.struts2.dispatcher.HttpParameters;
|
||||
import org.apache.struts2.dispatcher.Parameter;
|
||||
import org.apache.struts2.url.QueryStringBuilder;
|
||||
import org.apache.struts2.url.QueryStringParser;
|
||||
import org.apache.struts2.url.StrutsQueryStringBuilder;
|
||||
import org.apache.struts2.url.StrutsQueryStringParser;
|
||||
import org.apache.struts2.url.StrutsUrlDecoder;
|
||||
import org.apache.struts2.url.StrutsUrlEncoder;
|
||||
import org.apache.struts2.url.UrlDecoder;
|
||||
import org.apache.struts2.url.UrlEncoder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@@ -153,88 +158,90 @@ public class StrutsDefaultConfigurationProvider implements ConfigurationProvider
|
||||
|
||||
@Override
|
||||
public void register(ContainerBuilder builder, LocatableProperties props)
|
||||
throws ConfigurationException {
|
||||
throws ConfigurationException {
|
||||
|
||||
builder
|
||||
.factory(ObjectFactory.class)
|
||||
.factory(ActionFactory.class, DefaultActionFactory.class)
|
||||
.factory(ResultFactory.class, DefaultResultFactory.class)
|
||||
.factory(InterceptorFactory.class, DefaultInterceptorFactory.class)
|
||||
.factory(com.opensymphony.xwork2.factory.ValidatorFactory.class, com.opensymphony.xwork2.factory.DefaultValidatorFactory.class)
|
||||
.factory(ConverterFactory.class, StrutsConverterFactory.class)
|
||||
.factory(UnknownHandlerFactory.class, DefaultUnknownHandlerFactory.class)
|
||||
.factory(ObjectFactory.class)
|
||||
.factory(ActionFactory.class, DefaultActionFactory.class)
|
||||
.factory(ResultFactory.class, DefaultResultFactory.class)
|
||||
.factory(InterceptorFactory.class, DefaultInterceptorFactory.class)
|
||||
.factory(com.opensymphony.xwork2.factory.ValidatorFactory.class, com.opensymphony.xwork2.factory.DefaultValidatorFactory.class)
|
||||
.factory(ConverterFactory.class, StrutsConverterFactory.class)
|
||||
.factory(UnknownHandlerFactory.class, DefaultUnknownHandlerFactory.class)
|
||||
|
||||
.factory(ActionProxyFactory.class, DefaultActionProxyFactory.class, Scope.SINGLETON)
|
||||
.factory(ObjectTypeDeterminer.class, DefaultObjectTypeDeterminer.class, Scope.SINGLETON)
|
||||
.factory(ActionProxyFactory.class, DefaultActionProxyFactory.class, Scope.SINGLETON)
|
||||
.factory(ObjectTypeDeterminer.class, DefaultObjectTypeDeterminer.class, Scope.SINGLETON)
|
||||
|
||||
.factory(XWorkConverter.class, Scope.SINGLETON)
|
||||
.factory(XWorkBasicConverter.class, Scope.SINGLETON)
|
||||
.factory(ConversionPropertiesProcessor.class, StrutsConversionPropertiesProcessor.class, Scope.SINGLETON)
|
||||
.factory(ConversionFileProcessor.class, DefaultConversionFileProcessor.class, Scope.SINGLETON)
|
||||
.factory(ConversionAnnotationProcessor.class, DefaultConversionAnnotationProcessor.class, Scope.SINGLETON)
|
||||
.factory(TypeConverterCreator.class, StrutsTypeConverterCreator.class, Scope.SINGLETON)
|
||||
.factory(TypeConverterHolder.class, StrutsTypeConverterHolder.class, Scope.SINGLETON)
|
||||
.factory(XWorkConverter.class, Scope.SINGLETON)
|
||||
.factory(XWorkBasicConverter.class, Scope.SINGLETON)
|
||||
.factory(ConversionPropertiesProcessor.class, StrutsConversionPropertiesProcessor.class, Scope.SINGLETON)
|
||||
.factory(ConversionFileProcessor.class, DefaultConversionFileProcessor.class, Scope.SINGLETON)
|
||||
.factory(ConversionAnnotationProcessor.class, DefaultConversionAnnotationProcessor.class, Scope.SINGLETON)
|
||||
.factory(TypeConverterCreator.class, StrutsTypeConverterCreator.class, Scope.SINGLETON)
|
||||
.factory(TypeConverterHolder.class, StrutsTypeConverterHolder.class, Scope.SINGLETON)
|
||||
|
||||
.factory(FileManager.class, "system", DefaultFileManager.class, Scope.SINGLETON)
|
||||
.factory(FileManagerFactory.class, DefaultFileManagerFactory.class, Scope.SINGLETON)
|
||||
.factory(ValueStackFactory.class, OgnlValueStackFactory.class, Scope.SINGLETON)
|
||||
.factory(ValidatorFactory.class, DefaultValidatorFactory.class, Scope.SINGLETON)
|
||||
.factory(ValidatorFileParser.class, DefaultValidatorFileParser.class, Scope.SINGLETON)
|
||||
.factory(PatternMatcher.class, WildcardHelper.class, Scope.SINGLETON)
|
||||
.factory(ReflectionProvider.class, OgnlReflectionProvider.class, Scope.SINGLETON)
|
||||
.factory(ReflectionContextFactory.class, OgnlReflectionContextFactory.class, Scope.SINGLETON)
|
||||
.factory(FileManager.class, "system", DefaultFileManager.class, Scope.SINGLETON)
|
||||
.factory(FileManagerFactory.class, DefaultFileManagerFactory.class, Scope.SINGLETON)
|
||||
.factory(ValueStackFactory.class, OgnlValueStackFactory.class, Scope.SINGLETON)
|
||||
.factory(ValidatorFactory.class, DefaultValidatorFactory.class, Scope.SINGLETON)
|
||||
.factory(ValidatorFileParser.class, DefaultValidatorFileParser.class, Scope.SINGLETON)
|
||||
.factory(PatternMatcher.class, WildcardHelper.class, Scope.SINGLETON)
|
||||
.factory(ReflectionProvider.class, OgnlReflectionProvider.class, Scope.SINGLETON)
|
||||
.factory(ReflectionContextFactory.class, OgnlReflectionContextFactory.class, Scope.SINGLETON)
|
||||
|
||||
.factory(PropertyAccessor.class, CompoundRoot.class.getName(), CompoundRootAccessor.class, Scope.SINGLETON)
|
||||
.factory(PropertyAccessor.class, Object.class.getName(), ObjectAccessor.class, Scope.SINGLETON)
|
||||
.factory(PropertyAccessor.class, Iterator.class.getName(), XWorkIteratorPropertyAccessor.class, Scope.SINGLETON)
|
||||
.factory(PropertyAccessor.class, Enumeration.class.getName(), XWorkEnumerationAccessor.class, Scope.SINGLETON)
|
||||
.factory(PropertyAccessor.class, CompoundRoot.class.getName(), CompoundRootAccessor.class, Scope.SINGLETON)
|
||||
.factory(PropertyAccessor.class, Object.class.getName(), ObjectAccessor.class, Scope.SINGLETON)
|
||||
.factory(PropertyAccessor.class, Iterator.class.getName(), XWorkIteratorPropertyAccessor.class, Scope.SINGLETON)
|
||||
.factory(PropertyAccessor.class, Enumeration.class.getName(), XWorkEnumerationAccessor.class, Scope.SINGLETON)
|
||||
|
||||
.factory(UnknownHandlerManager.class, DefaultUnknownHandlerManager.class, Scope.SINGLETON)
|
||||
.factory(UnknownHandlerManager.class, DefaultUnknownHandlerManager.class, Scope.SINGLETON)
|
||||
|
||||
// silly workarounds for ognl since there is no way to flush its caches
|
||||
.factory(PropertyAccessor.class, List.class.getName(), XWorkListPropertyAccessor.class, Scope.SINGLETON)
|
||||
.factory(PropertyAccessor.class, ArrayList.class.getName(), XWorkListPropertyAccessor.class, Scope.SINGLETON)
|
||||
.factory(PropertyAccessor.class, HashSet.class.getName(), XWorkCollectionPropertyAccessor.class, Scope.SINGLETON)
|
||||
.factory(PropertyAccessor.class, Set.class.getName(), XWorkCollectionPropertyAccessor.class, Scope.SINGLETON)
|
||||
.factory(PropertyAccessor.class, HashMap.class.getName(), XWorkMapPropertyAccessor.class, Scope.SINGLETON)
|
||||
.factory(PropertyAccessor.class, Map.class.getName(), XWorkMapPropertyAccessor.class, Scope.SINGLETON)
|
||||
.factory(PropertyAccessor.class, Collection.class.getName(), XWorkCollectionPropertyAccessor.class, Scope.SINGLETON)
|
||||
.factory(PropertyAccessor.class, ObjectProxy.class.getName(), ObjectProxyPropertyAccessor.class, Scope.SINGLETON)
|
||||
.factory(PropertyAccessor.class, HttpParameters.class.getName(), HttpParametersPropertyAccessor.class, Scope.SINGLETON)
|
||||
.factory(PropertyAccessor.class, Parameter.class.getName(), ParameterPropertyAccessor.class, Scope.SINGLETON)
|
||||
// silly workarounds for ognl since there is no way to flush its caches
|
||||
.factory(PropertyAccessor.class, List.class.getName(), XWorkListPropertyAccessor.class, Scope.SINGLETON)
|
||||
.factory(PropertyAccessor.class, ArrayList.class.getName(), XWorkListPropertyAccessor.class, Scope.SINGLETON)
|
||||
.factory(PropertyAccessor.class, HashSet.class.getName(), XWorkCollectionPropertyAccessor.class, Scope.SINGLETON)
|
||||
.factory(PropertyAccessor.class, Set.class.getName(), XWorkCollectionPropertyAccessor.class, Scope.SINGLETON)
|
||||
.factory(PropertyAccessor.class, HashMap.class.getName(), XWorkMapPropertyAccessor.class, Scope.SINGLETON)
|
||||
.factory(PropertyAccessor.class, Map.class.getName(), XWorkMapPropertyAccessor.class, Scope.SINGLETON)
|
||||
.factory(PropertyAccessor.class, Collection.class.getName(), XWorkCollectionPropertyAccessor.class, Scope.SINGLETON)
|
||||
.factory(PropertyAccessor.class, ObjectProxy.class.getName(), ObjectProxyPropertyAccessor.class, Scope.SINGLETON)
|
||||
.factory(PropertyAccessor.class, HttpParameters.class.getName(), HttpParametersPropertyAccessor.class, Scope.SINGLETON)
|
||||
.factory(PropertyAccessor.class, Parameter.class.getName(), ParameterPropertyAccessor.class, Scope.SINGLETON)
|
||||
|
||||
.factory(MethodAccessor.class, Object.class.getName(), XWorkMethodAccessor.class, Scope.SINGLETON)
|
||||
.factory(MethodAccessor.class, CompoundRoot.class.getName(), CompoundRootAccessor.class, Scope.SINGLETON)
|
||||
.factory(MethodAccessor.class, Object.class.getName(), XWorkMethodAccessor.class, Scope.SINGLETON)
|
||||
.factory(MethodAccessor.class, CompoundRoot.class.getName(), CompoundRootAccessor.class, Scope.SINGLETON)
|
||||
|
||||
.factory(TextParser.class, OgnlTextParser.class, Scope.SINGLETON)
|
||||
.factory(TextParser.class, OgnlTextParser.class, Scope.SINGLETON)
|
||||
|
||||
.factory(NullHandler.class, Object.class.getName(), InstantiatingNullHandler.class, Scope.SINGLETON)
|
||||
.factory(ActionValidatorManager.class, AnnotationActionValidatorManager.class, Scope.SINGLETON)
|
||||
.factory(ActionValidatorManager.class, "no-annotations", DefaultActionValidatorManager.class, Scope.SINGLETON)
|
||||
.factory(NullHandler.class, Object.class.getName(), InstantiatingNullHandler.class, Scope.SINGLETON)
|
||||
.factory(ActionValidatorManager.class, AnnotationActionValidatorManager.class, Scope.SINGLETON)
|
||||
.factory(ActionValidatorManager.class, "no-annotations", DefaultActionValidatorManager.class, Scope.SINGLETON)
|
||||
|
||||
.factory(TextProvider.class, "system", DefaultTextProvider.class, Scope.SINGLETON)
|
||||
.factory(LocalizedTextProvider.class, StrutsLocalizedTextProvider.class, Scope.SINGLETON)
|
||||
.factory(TextProviderFactory.class, StrutsTextProviderFactory.class, Scope.SINGLETON)
|
||||
.factory(LocaleProviderFactory.class, DefaultLocaleProviderFactory.class, Scope.SINGLETON)
|
||||
.factory(TextProvider.class, "system", DefaultTextProvider.class, Scope.SINGLETON)
|
||||
.factory(LocalizedTextProvider.class, StrutsLocalizedTextProvider.class, Scope.SINGLETON)
|
||||
.factory(TextProviderFactory.class, StrutsTextProviderFactory.class, Scope.SINGLETON)
|
||||
.factory(LocaleProviderFactory.class, DefaultLocaleProviderFactory.class, Scope.SINGLETON)
|
||||
|
||||
.factory(ExpressionCacheFactory.class, "defaultOgnlExpressionCacheFactory", DefaultOgnlExpressionCacheFactory.class, Scope.SINGLETON)
|
||||
.factory(BeanInfoCacheFactory.class, "defaultOgnlBeanInfoCacheFactory", DefaultOgnlBeanInfoCacheFactory.class, Scope.SINGLETON)
|
||||
.factory(OgnlUtil.class, Scope.SINGLETON)
|
||||
.factory(CollectionConverter.class, Scope.SINGLETON)
|
||||
.factory(ArrayConverter.class, Scope.SINGLETON)
|
||||
.factory(DateConverter.class, Scope.SINGLETON)
|
||||
.factory(NumberConverter.class, Scope.SINGLETON)
|
||||
.factory(StringConverter.class, Scope.SINGLETON)
|
||||
.factory(ExpressionCacheFactory.class, DefaultOgnlExpressionCacheFactory.class, Scope.SINGLETON)
|
||||
.factory(BeanInfoCacheFactory.class, DefaultOgnlBeanInfoCacheFactory.class, Scope.SINGLETON)
|
||||
.factory(OgnlUtil.class, Scope.SINGLETON)
|
||||
.factory(CollectionConverter.class, Scope.SINGLETON)
|
||||
.factory(ArrayConverter.class, Scope.SINGLETON)
|
||||
.factory(DateConverter.class, Scope.SINGLETON)
|
||||
.factory(NumberConverter.class, Scope.SINGLETON)
|
||||
.factory(StringConverter.class, Scope.SINGLETON)
|
||||
|
||||
.factory(ExcludedPatternsChecker.class, DefaultExcludedPatternsChecker.class, Scope.PROTOTYPE)
|
||||
.factory(AcceptedPatternsChecker.class, DefaultAcceptedPatternsChecker.class, Scope.PROTOTYPE)
|
||||
.factory(NotExcludedAcceptedPatternsChecker.class, DefaultNotExcludedAcceptedPatternsChecker.class
|
||||
, Scope.SINGLETON)
|
||||
.factory(ExcludedPatternsChecker.class, DefaultExcludedPatternsChecker.class, Scope.PROTOTYPE)
|
||||
.factory(AcceptedPatternsChecker.class, DefaultAcceptedPatternsChecker.class, Scope.PROTOTYPE)
|
||||
.factory(NotExcludedAcceptedPatternsChecker.class, DefaultNotExcludedAcceptedPatternsChecker.class
|
||||
, Scope.SINGLETON)
|
||||
|
||||
.factory(ValueSubstitutor.class, EnvsValueSubstitutor.class, Scope.SINGLETON)
|
||||
.factory(ValueSubstitutor.class, EnvsValueSubstitutor.class, Scope.SINGLETON)
|
||||
|
||||
.factory(DateFormatter.class, "simpleDateFormatter", SimpleDateFormatAdapter.class, Scope.SINGLETON)
|
||||
.factory(DateFormatter.class, "dateTimeFormatter", DateTimeFormatterAdapter.class, Scope.SINGLETON)
|
||||
.factory(QueryStringBuilder.class, StrutsQueryStringBuilder.class, Scope.SINGLETON)
|
||||
.factory(QueryStringParser.class, StrutsQueryStringParser.class, Scope.SINGLETON)
|
||||
.factory(UrlEncoder.class, StrutsUrlEncoder.class, Scope.SINGLETON)
|
||||
.factory(UrlDecoder.class, StrutsUrlDecoder.class, Scope.SINGLETON)
|
||||
;
|
||||
|
||||
props.setProperty(StrutsConstants.STRUTS_ENABLE_DYNAMIC_METHOD_INVOCATION, Boolean.FALSE.toString());
|
||||
|
||||
@@ -19,10 +19,26 @@ import com.opensymphony.xwork2.inject.util.ReferenceCache;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.*;
|
||||
import java.lang.reflect.AccessibleObject;
|
||||
import java.lang.reflect.AnnotatedElement;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Member;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.ReflectPermission;
|
||||
import java.security.AccessControlException;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Default {@link Container} implementation.
|
||||
@@ -39,11 +55,7 @@ class ContainerImpl implements Container {
|
||||
this.factories = factories;
|
||||
final Map<Class<?>, Set<String>> map = new HashMap<>();
|
||||
for (Key<?> key : factories.keySet()) {
|
||||
Set<String> names = map.get(key.getType());
|
||||
if (names == null) {
|
||||
names = new HashSet<>();
|
||||
map.put(key.getType(), names);
|
||||
}
|
||||
Set<String> names = map.computeIfAbsent(key.getType(), k -> new HashSet<>());
|
||||
names.add(key.getName());
|
||||
}
|
||||
|
||||
@@ -63,20 +75,20 @@ class ContainerImpl implements Container {
|
||||
* Field and method injectors.
|
||||
*/
|
||||
final Map<Class<?>, List<Injector>> injectors =
|
||||
new ReferenceCache<Class<?>, List<Injector>>() {
|
||||
@Override
|
||||
protected List<Injector> create(Class<?> key) {
|
||||
List<Injector> injectors = new ArrayList<>();
|
||||
addInjectors(key, injectors);
|
||||
return injectors;
|
||||
}
|
||||
};
|
||||
new ReferenceCache<Class<?>, List<Injector>>() {
|
||||
@Override
|
||||
protected List<Injector> create(Class<?> key) {
|
||||
List<Injector> injectors = new ArrayList<>();
|
||||
addInjectors(key, injectors);
|
||||
return injectors;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Recursively adds injectors for fields and methods from the given class to the given list. Injects parent classes
|
||||
* before sub classes.
|
||||
*/
|
||||
void addInjectors(Class clazz, List<Injector> injectors) {
|
||||
void addInjectors(Class<?> clazz, List<Injector> injectors) {
|
||||
if (clazz == Object.class) {
|
||||
return;
|
||||
}
|
||||
@@ -97,38 +109,24 @@ class ContainerImpl implements Container {
|
||||
addInjectorsForMethods(clazz.getDeclaredMethods(), true, injectors);
|
||||
}
|
||||
|
||||
callInContext(new ContextualCallable<Void>() {
|
||||
public Void call(InternalContext context) {
|
||||
for (Injector injector : injectors) {
|
||||
injector.inject(context, null);
|
||||
}
|
||||
return null;
|
||||
callInContext((ContextualCallable<Void>) context -> {
|
||||
for (Injector injector : injectors) {
|
||||
injector.inject(context, null);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
void addInjectorsForMethods(Method[] methods, boolean statics, List<Injector> injectors) {
|
||||
addInjectorsForMembers(Arrays.asList(methods), statics, injectors,
|
||||
new InjectorFactory<Method>() {
|
||||
public Injector create(ContainerImpl container, Method method,
|
||||
String name) throws MissingDependencyException {
|
||||
return new MethodInjector(container, method, name);
|
||||
}
|
||||
});
|
||||
addInjectorsForMembers(Arrays.asList(methods), statics, injectors, MethodInjector::new);
|
||||
}
|
||||
|
||||
void addInjectorsForFields(Field[] fields, boolean statics, List<Injector> injectors) {
|
||||
addInjectorsForMembers(Arrays.asList(fields), statics, injectors,
|
||||
new InjectorFactory<Field>() {
|
||||
public Injector create(ContainerImpl container, Field field,
|
||||
String name) throws MissingDependencyException {
|
||||
return new FieldInjector(container, field, name);
|
||||
}
|
||||
});
|
||||
addInjectorsForMembers(Arrays.asList(fields), statics, injectors, FieldInjector::new);
|
||||
}
|
||||
|
||||
<M extends Member & AnnotatedElement> void addInjectorsForMembers(
|
||||
List<M> members, boolean statics, List<Injector> injectors, InjectorFactory<M> injectorFactory) {
|
||||
List<M> members, boolean statics, List<Injector> injectors, InjectorFactory<M> injectorFactory) {
|
||||
for (M member : members) {
|
||||
if (isStatic(member) == statics) {
|
||||
Inject inject = member.getAnnotation(Inject.class);
|
||||
@@ -148,12 +146,12 @@ class ContainerImpl implements Container {
|
||||
interface InjectorFactory<M extends Member & AnnotatedElement> {
|
||||
|
||||
Injector create(ContainerImpl container, M member, String name)
|
||||
throws MissingDependencyException;
|
||||
throws MissingDependencyException;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a given {@link Member} is static or not.
|
||||
*
|
||||
*
|
||||
* @param member checked for the static modifier.
|
||||
* @return true if member is static, false otherwise.
|
||||
*/
|
||||
@@ -163,13 +161,13 @@ class ContainerImpl implements Container {
|
||||
|
||||
/**
|
||||
* Determines if a given {@link Member} is considered to be public for reflection usage or not.
|
||||
*
|
||||
*
|
||||
* @param member checked to see if it is public for reflection usage.
|
||||
* @return true if member is public for reflection usage, false otherwise.
|
||||
*/
|
||||
private static boolean isPublicForReflection(Member member) {
|
||||
return Modifier.isPublic(member.getModifiers()) &&
|
||||
Modifier.isPublic(member.getDeclaringClass().getModifiers());
|
||||
Modifier.isPublic(member.getDeclaringClass().getModifiers());
|
||||
}
|
||||
|
||||
static class FieldInjector implements Injector {
|
||||
@@ -179,7 +177,7 @@ class ContainerImpl implements Container {
|
||||
final ExternalContext<?> externalContext;
|
||||
|
||||
public FieldInjector(ContainerImpl container, Field field, String name)
|
||||
throws MissingDependencyException {
|
||||
throws MissingDependencyException {
|
||||
this.field = field;
|
||||
if (!isPublicForReflection(field) && !field.isAccessible()) {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
@@ -190,7 +188,7 @@ class ContainerImpl implements Container {
|
||||
field.setAccessible(true);
|
||||
} catch (AccessControlException e) {
|
||||
throw new DependencyException("Security manager in use, could not access field: "
|
||||
+ field.getDeclaringClass().getName() + "(" + field.getName() + ")", e);
|
||||
+ field.getDeclaringClass().getName() + "(" + field.getName() + ")", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,8 +223,12 @@ class ContainerImpl implements Container {
|
||||
* @param parameterTypes parameter types
|
||||
* @return injections
|
||||
*/
|
||||
<M extends AccessibleObject & Member> ParameterInjector<?>[]
|
||||
getParametersInjectors(M member, Annotation[][] annotations, Class[] parameterTypes, String defaultName) throws MissingDependencyException {
|
||||
<M extends AccessibleObject & Member> ParameterInjector<?>[] getParametersInjectors(
|
||||
M member,
|
||||
Annotation[][] annotations,
|
||||
Class<?>[] parameterTypes,
|
||||
String defaultName
|
||||
) throws MissingDependencyException {
|
||||
final List<ParameterInjector<?>> parameterInjectors = new ArrayList<>();
|
||||
|
||||
final Iterator<Annotation[]> annotationsIterator = Arrays.asList(annotations).iterator();
|
||||
@@ -247,12 +249,11 @@ class ContainerImpl implements Container {
|
||||
}
|
||||
|
||||
final ExternalContext<T> externalContext = ExternalContext.newInstance(member, key, this);
|
||||
return new ParameterInjector<T>(externalContext, factory);
|
||||
return new ParameterInjector<>(externalContext, factory);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private ParameterInjector<?>[] toArray(List<ParameterInjector<?>> parameterInjections) {
|
||||
return parameterInjections.toArray(new ParameterInjector[parameterInjections.size()]);
|
||||
return parameterInjections.toArray(new ParameterInjector[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -261,7 +262,7 @@ class ContainerImpl implements Container {
|
||||
Inject findInject(Annotation[] annotations) {
|
||||
for (Annotation annotation : annotations) {
|
||||
if (annotation.annotationType() == Inject.class) {
|
||||
return Inject.class.cast(annotation);
|
||||
return (Inject) annotation;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -283,7 +284,7 @@ class ContainerImpl implements Container {
|
||||
method.setAccessible(true);
|
||||
} catch (AccessControlException e) {
|
||||
throw new DependencyException("Security manager in use, could not access method: "
|
||||
+ name + "(" + method.getName() + ")", e);
|
||||
+ name + "(" + method.getName() + ")", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -292,7 +293,7 @@ class ContainerImpl implements Container {
|
||||
throw new DependencyException(method + " has no parameters to inject.");
|
||||
}
|
||||
parameterInjectors = container.getParametersInjectors(
|
||||
method, method.getParameterAnnotations(), parameterTypes, name);
|
||||
method, method.getParameterAnnotations(), parameterTypes, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -305,14 +306,12 @@ class ContainerImpl implements Container {
|
||||
}
|
||||
}
|
||||
|
||||
Map<Class<?>, ConstructorInjector> constructors =
|
||||
new ReferenceCache<Class<?>, ConstructorInjector>() {
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
protected ConstructorInjector<?> create(Class<?> implementation) {
|
||||
return new ConstructorInjector(ContainerImpl.this, implementation);
|
||||
}
|
||||
};
|
||||
Map<Class<?>, ConstructorInjector<?>> constructors = new ReferenceCache<Class<?>, ConstructorInjector<?>>() {
|
||||
@Override
|
||||
protected ConstructorInjector<?> create(Class<?> implementation) {
|
||||
return new ConstructorInjector<>(ContainerImpl.this, implementation);
|
||||
}
|
||||
};
|
||||
|
||||
static class ConstructorInjector<T> {
|
||||
|
||||
@@ -334,7 +333,7 @@ class ContainerImpl implements Container {
|
||||
constructor.setAccessible(true);
|
||||
} catch (AccessControlException e) {
|
||||
throw new DependencyException("Security manager in use, could not access constructor: "
|
||||
+ implementation.getName() + "(" + constructor.getName() + ")", e);
|
||||
+ implementation.getName() + "(" + constructor.getName() + ")", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -359,14 +358,14 @@ class ContainerImpl implements Container {
|
||||
}
|
||||
|
||||
ParameterInjector<?>[] constructParameterInjector(
|
||||
Inject inject, ContainerImpl container, Constructor<T> constructor) throws MissingDependencyException {
|
||||
Inject inject, ContainerImpl container, Constructor<T> constructor) throws MissingDependencyException {
|
||||
return constructor.getParameterTypes().length == 0
|
||||
? null // default constructor.
|
||||
: container.getParametersInjectors(
|
||||
constructor,
|
||||
constructor.getParameterAnnotations(),
|
||||
constructor.getParameterTypes(),
|
||||
inject.value()
|
||||
? null // default constructor.
|
||||
: container.getParametersInjectors(
|
||||
constructor,
|
||||
constructor.getParameterAnnotations(),
|
||||
constructor.getParameterTypes(),
|
||||
inject.value()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -378,7 +377,7 @@ class ContainerImpl implements Container {
|
||||
if (constructor.getAnnotation(Inject.class) != null) {
|
||||
if (found != null) {
|
||||
throw new DependencyException("More than one constructor annotated"
|
||||
+ " with @Inject found in " + implementation + ".");
|
||||
+ " with @Inject found in " + implementation + ".");
|
||||
}
|
||||
found = constructor;
|
||||
}
|
||||
@@ -466,7 +465,7 @@ class ContainerImpl implements Container {
|
||||
}
|
||||
}
|
||||
|
||||
private static Object[] getParameters(Member member, InternalContext context, ParameterInjector[] parameterInjectors) {
|
||||
private static Object[] getParameters(Member member, InternalContext context, ParameterInjector<?>[] parameterInjectors) {
|
||||
if (parameterInjectors == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -494,13 +493,12 @@ class ContainerImpl implements Container {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
<T> T getInstance(Class<T> type, String name, InternalContext context) {
|
||||
final ExternalContext<?> previous = context.getExternalContext();
|
||||
final Key<T> key = Key.newInstance(type, name);
|
||||
context.setExternalContext(ExternalContext.newInstance(null, key, this));
|
||||
try {
|
||||
final InternalFactory o = getFactory(key);
|
||||
final InternalFactory<? extends T> o = getFactory(key);
|
||||
if (o != null) {
|
||||
return getFactory(key).create(context);
|
||||
} else {
|
||||
@@ -517,39 +515,25 @@ class ContainerImpl implements Container {
|
||||
|
||||
@Override
|
||||
public void inject(final Object o) {
|
||||
callInContext(new ContextualCallable<Void>() {
|
||||
public Void call(InternalContext context) {
|
||||
inject(o, context);
|
||||
return null;
|
||||
}
|
||||
callInContext((ContextualCallable<Void>) context -> {
|
||||
inject(o, context);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T inject(final Class<T> implementation) {
|
||||
return callInContext(new ContextualCallable<T>() {
|
||||
public T call(InternalContext context) {
|
||||
return inject(implementation, context);
|
||||
}
|
||||
});
|
||||
return callInContext(context -> inject(implementation, context));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getInstance(final Class<T> type, final String name) {
|
||||
return callInContext(new ContextualCallable<T>() {
|
||||
public T call(InternalContext context) {
|
||||
return getInstance(type, name, context);
|
||||
}
|
||||
});
|
||||
return callInContext(context -> getInstance(type, name, context));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getInstance(final Class<T> type) {
|
||||
return callInContext(new ContextualCallable<T>() {
|
||||
public T call(InternalContext context) {
|
||||
return getInstance(type, context);
|
||||
}
|
||||
});
|
||||
return callInContext(context -> getInstance(type, context));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -561,12 +545,7 @@ class ContainerImpl implements Container {
|
||||
return names;
|
||||
}
|
||||
|
||||
ThreadLocal<Object[]> localContext = new ThreadLocal<Object[]>() {
|
||||
@Override
|
||||
protected Object[] initialValue() {
|
||||
return new Object[1];
|
||||
}
|
||||
};
|
||||
ThreadLocal<Object[]> localContext = ThreadLocal.withInitial(() -> new Object[1]);
|
||||
|
||||
/**
|
||||
* Looks up thread local context. Creates (and removes) a new context if necessary.
|
||||
@@ -598,7 +577,7 @@ class ContainerImpl implements Container {
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
<T> ConstructorInjector<T> getConstructor(Class<T> implementation) {
|
||||
return constructors.get(implementation);
|
||||
return (ConstructorInjector<T>) constructors.get(implementation);
|
||||
}
|
||||
|
||||
final ThreadLocal<Object> localScopeStrategy = new ThreadLocal<>();
|
||||
|
||||
@@ -23,23 +23,39 @@ import com.opensymphony.xwork2.ActionInvocation;
|
||||
/**
|
||||
* Provides default implementations of optional lifecycle methods
|
||||
*/
|
||||
public abstract class AbstractInterceptor implements Interceptor {
|
||||
public abstract class AbstractInterceptor implements ConditionalInterceptor {
|
||||
|
||||
private boolean disabled;
|
||||
|
||||
/**
|
||||
* Does nothing
|
||||
*/
|
||||
public void init() {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Does nothing
|
||||
*/
|
||||
public void destroy() {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Override to handle interception
|
||||
*/
|
||||
public abstract String intercept(ActionInvocation invocation) throws Exception;
|
||||
|
||||
/**
|
||||
* Allows to skip executing a given interceptor, just define {@code <param name="disabled">true</param>}
|
||||
* or use other way to override interceptor's parameters, see
|
||||
* <a href="https://struts.apache.org/core-developers/interceptors#interceptor-parameter-overriding">docs</a>.
|
||||
* @param disable if set to true, execution of a given interceptor will be skipped.
|
||||
*/
|
||||
public void setDisabled(String disable) {
|
||||
this.disabled = Boolean.parseBoolean(disable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldIntercept(ActionInvocation invocation) {
|
||||
return !this.disabled;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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 com.opensymphony.xwork2.interceptor;
|
||||
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
|
||||
/**
|
||||
* A marking interface, when implemented allows to conditionally execute a given interceptor
|
||||
* within the current action invocation.
|
||||
*
|
||||
* @since Struts 6.1.1
|
||||
*/
|
||||
public interface ConditionalInterceptor extends Interceptor {
|
||||
|
||||
/**
|
||||
* Determines if a given interceptor should be executed in the current processing of action invocation.
|
||||
*
|
||||
* @param invocation current {@link ActionInvocation} to determine if the interceptor should be executed
|
||||
* @return true if the given interceptor should be included in the current action invocation
|
||||
* @since 6.1.1
|
||||
*/
|
||||
boolean shouldIntercept(ActionInvocation invocation);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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 com.opensymphony.xwork2.interceptor;
|
||||
|
||||
/**
|
||||
* This interface is implemented by actions that want to declare acceptable parameter value. Works in conjunction with {@link
|
||||
* ParametersInterceptor}. For example, actions may want to create a white list of parameter values they will accept or a
|
||||
* blacklist of parameter values they will reject to prevent clients from setting other unexpected (and possibly dangerous)
|
||||
* parameter values.
|
||||
*/
|
||||
public interface ParameterValueAware {
|
||||
|
||||
/**
|
||||
* Tests if the the action will accept the parameter with the given value.
|
||||
*
|
||||
* @param parameterValue the parameter value
|
||||
* @return <tt>true</tt> if accepted, <tt>false</tt> otherwise
|
||||
*/
|
||||
boolean acceptableParameterValue(String parameterValue);
|
||||
|
||||
}
|
||||
+165
-11
@@ -26,6 +26,7 @@ import com.opensymphony.xwork2.security.AcceptedPatternsChecker;
|
||||
import com.opensymphony.xwork2.security.ExcludedPatternsChecker;
|
||||
import com.opensymphony.xwork2.util.ClearableValueStack;
|
||||
import com.opensymphony.xwork2.util.MemberAccessValueStack;
|
||||
import com.opensymphony.xwork2.util.TextParseUtil;
|
||||
import com.opensymphony.xwork2.util.ValueStack;
|
||||
import com.opensymphony.xwork2.util.ValueStackFactory;
|
||||
import com.opensymphony.xwork2.util.reflection.ReflectionContextState;
|
||||
@@ -33,12 +34,15 @@ import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
import org.apache.struts2.dispatcher.Parameter;
|
||||
import org.apache.struts2.dispatcher.HttpParameters;
|
||||
import org.apache.struts2.dispatcher.Parameter;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -62,6 +66,8 @@ public class ParametersInterceptor extends MethodFilterInterceptor {
|
||||
private ValueStackFactory valueStackFactory;
|
||||
private ExcludedPatternsChecker excludedPatterns;
|
||||
private AcceptedPatternsChecker acceptedPatterns;
|
||||
private Set<Pattern> excludedValuePatterns = null;
|
||||
private Set<Pattern> acceptedValuePatterns = null;
|
||||
|
||||
@Inject
|
||||
public void setValueStackFactory(ValueStackFactory valueStackFactory) {
|
||||
@@ -183,8 +189,10 @@ public class ParametersInterceptor extends MethodFilterInterceptor {
|
||||
|
||||
for (Map.Entry<String, Parameter> entry : params.entrySet()) {
|
||||
String parameterName = entry.getKey();
|
||||
boolean isAcceptableParameter = isAcceptableParameter(parameterName, action);
|
||||
isAcceptableParameter &= isAcceptableParameterValue(entry.getValue(), action);
|
||||
|
||||
if (isAcceptableParameter(parameterName, action)) {
|
||||
if (isAcceptableParameter) {
|
||||
acceptableParameters.put(parameterName, entry.getValue());
|
||||
}
|
||||
}
|
||||
@@ -237,8 +245,8 @@ public class ParametersInterceptor extends MethodFilterInterceptor {
|
||||
if (action instanceof TextProvider) {
|
||||
TextProvider tp = (TextProvider) action;
|
||||
developerNotification = tp.getText("devmode.notification",
|
||||
"Developer Notification:\n{0}",
|
||||
new String[]{developerNotification}
|
||||
"Developer Notification:\n{0}",
|
||||
new String[]{developerNotification}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -264,6 +272,23 @@ public class ParametersInterceptor extends MethodFilterInterceptor {
|
||||
return acceptableName(name) && (parameterNameAware == null || parameterNameAware.acceptableParameterName(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if parameter value can be accepted or thrown away
|
||||
*
|
||||
* @param param the parameter
|
||||
* @param action current action
|
||||
* @return true if parameter is accepted
|
||||
*/
|
||||
protected boolean isAcceptableParameterValue(Parameter param, Object action) {
|
||||
ParameterValueAware parameterValueAware = (action instanceof ParameterValueAware) ? (ParameterValueAware) action : null;
|
||||
boolean acceptableParamValue = (parameterValueAware == null || parameterValueAware.acceptableParameterValue(param.getValue()));
|
||||
if (hasParamValuesToExclude() || hasParamValuesToAccept()) {
|
||||
// Additional validations to process
|
||||
acceptableParamValue &= acceptableValue(param.getName(), param.getValue());
|
||||
}
|
||||
return acceptableParamValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an instance of the comparator to use for the ordered sorting. Override this
|
||||
* method to customize the ordering of the parameters as they are set to the
|
||||
@@ -291,6 +316,15 @@ public class ParametersInterceptor extends MethodFilterInterceptor {
|
||||
return logEntry.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the name passed is:
|
||||
* * Within the max length of a parameter name
|
||||
* * Is not excluded
|
||||
* * Is accepted
|
||||
*
|
||||
* @param name - Name to check
|
||||
* @return true if accepted
|
||||
*/
|
||||
protected boolean acceptableName(String name) {
|
||||
if (isIgnoredDMI(name)) {
|
||||
LOG.trace("DMI is enabled, ignoring DMI method: {}", name);
|
||||
@@ -311,14 +345,37 @@ public class ParametersInterceptor extends MethodFilterInterceptor {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates:
|
||||
* * Value is null/blank
|
||||
* * Value is not excluded
|
||||
* * Value is accepted
|
||||
*
|
||||
* @param name - Param name (for logging)
|
||||
* @param value - value to check
|
||||
* @return true if accepted
|
||||
*/
|
||||
protected boolean acceptableValue(String name, String value) {
|
||||
boolean accepted = (value == null || value.isEmpty() || (!isParamValueExcluded(value) && isParamValueAccepted(value)));
|
||||
if (!accepted) {
|
||||
String message = "Value [{}] of parameter [{}] was not accepted and will be dropped!";
|
||||
if (devMode) {
|
||||
LOG.warn(message, value, name);
|
||||
} else {
|
||||
LOG.debug(message, value, name);
|
||||
}
|
||||
}
|
||||
return accepted;
|
||||
}
|
||||
|
||||
protected boolean isWithinLengthLimit(String name) {
|
||||
boolean matchLength = name.length() <= paramNameMaxLength;
|
||||
if (!matchLength) {
|
||||
if (devMode) { // warn only when in devMode
|
||||
LOG.warn("Parameter [{}] is too long, allowed length is [{}]. Use Interceptor Parameter Overriding " +
|
||||
"to override the limit, see more at\n" +
|
||||
"https://struts.apache.org/core-developers/interceptors.html#interceptor-parameter-overriding",
|
||||
name, paramNameMaxLength);
|
||||
"to override the limit, see more at\n" +
|
||||
"https://struts.apache.org/core-developers/interceptors.html#interceptor-parameter-overriding",
|
||||
name, paramNameMaxLength);
|
||||
} else {
|
||||
LOG.warn("Parameter [{}] is too long, allowed length is [{}]", name, paramNameMaxLength);
|
||||
}
|
||||
@@ -332,8 +389,8 @@ public class ParametersInterceptor extends MethodFilterInterceptor {
|
||||
return true;
|
||||
} else if (devMode) { // warn only when in devMode
|
||||
LOG.warn("Parameter [{}] didn't match accepted pattern [{}]! See Accepted / Excluded patterns at\n" +
|
||||
"https://struts.apache.org/security/#accepted--excluded-patterns",
|
||||
paramName, result.getAcceptedPattern());
|
||||
"https://struts.apache.org/security/#accepted--excluded-patterns",
|
||||
paramName, result.getAcceptedPattern());
|
||||
} else {
|
||||
LOG.debug("Parameter [{}] didn't match accepted pattern [{}]!", paramName, result.getAcceptedPattern());
|
||||
}
|
||||
@@ -345,8 +402,8 @@ public class ParametersInterceptor extends MethodFilterInterceptor {
|
||||
if (result.isExcluded()) {
|
||||
if (devMode) { // warn only when in devMode
|
||||
LOG.warn("Parameter [{}] matches excluded pattern [{}]! See Accepted / Excluded patterns at\n" +
|
||||
"https://struts.apache.org/security/#accepted--excluded-patterns",
|
||||
paramName, result.getExcludedPattern());
|
||||
"https://struts.apache.org/security/#accepted--excluded-patterns",
|
||||
paramName, result.getExcludedPattern());
|
||||
} else {
|
||||
LOG.debug("Parameter [{}] matches excluded pattern [{}]!", paramName, result.getExcludedPattern());
|
||||
}
|
||||
@@ -355,6 +412,54 @@ public class ParametersInterceptor extends MethodFilterInterceptor {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean isParamValueExcluded(String value) {
|
||||
if (!hasParamValuesToExclude()) {
|
||||
LOG.debug("'excludedValuePatterns' not defined so anything is allowed");
|
||||
return false;
|
||||
}
|
||||
for (Pattern excludedValuePattern : excludedValuePatterns) {
|
||||
if (excludedValuePattern.matcher(value).matches()) {
|
||||
if (devMode) {
|
||||
LOG.warn("Parameter value [{}] matches excluded pattern [{}]! See Accepting/Excluding parameter values at\n" +
|
||||
"https://struts.apache.org/core-developers/parameters-interceptor#excluding-parameter-values",
|
||||
value, excludedValuePatterns);
|
||||
} else {
|
||||
LOG.debug("Parameter value [{}] matches excluded pattern [{}]", value, excludedValuePattern);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean isParamValueAccepted(String value) {
|
||||
if (!hasParamValuesToAccept()) {
|
||||
LOG.debug("'acceptedValuePatterns' not defined so anything is allowed");
|
||||
return true;
|
||||
}
|
||||
for (Pattern acceptedValuePattern : acceptedValuePatterns) {
|
||||
if (acceptedValuePattern.matcher(value).matches()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (devMode) {
|
||||
LOG.warn("Parameter value [{}] didn't match accepted pattern [{}]! See Accepting/Excluding parameter values at\n" +
|
||||
"https://struts.apache.org/core-developers/parameters-interceptor#excluding-parameter-values",
|
||||
value, acceptedValuePatterns);
|
||||
} else {
|
||||
LOG.debug("Parameter value [{}] was not accepted!", value);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean hasParamValuesToExclude() {
|
||||
return excludedValuePatterns != null && excludedValuePatterns.size() > 0;
|
||||
}
|
||||
|
||||
private boolean hasParamValuesToAccept() {
|
||||
return acceptedValuePatterns != null && acceptedValuePatterns.size() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to order the parameters or not
|
||||
*
|
||||
@@ -397,4 +502,53 @@ public class ParametersInterceptor extends MethodFilterInterceptor {
|
||||
excludedPatterns.setExcludedPatterns(commaDelim);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a comma-delimited list of regular expressions to match
|
||||
* values of parameters that should be accepted and included in the parameter map.
|
||||
*
|
||||
* @param commaDelimitedPatterns A comma-delimited set of regular expressions
|
||||
*/
|
||||
public void setAcceptedValuePatterns(String commaDelimitedPatterns) {
|
||||
Set<String> patterns = TextParseUtil.commaDelimitedStringToSet(commaDelimitedPatterns);
|
||||
if (acceptedValuePatterns == null) {
|
||||
// Limit unwanted log entries (for 1st call, acceptedValuePatterns null)
|
||||
LOG.debug("Sets accepted value patterns to [{}], note this may impact the safety of your application!", patterns);
|
||||
} else {
|
||||
LOG.warn("Replacing accepted patterns [{}] with [{}], be aware that this may impact safety of your application!",
|
||||
acceptedValuePatterns, patterns);
|
||||
}
|
||||
acceptedValuePatterns = new HashSet<>(patterns.size());
|
||||
try {
|
||||
for (String pattern : patterns) {
|
||||
acceptedValuePatterns.add(Pattern.compile(pattern, Pattern.CASE_INSENSITIVE));
|
||||
}
|
||||
} finally {
|
||||
acceptedValuePatterns = Collections.unmodifiableSet(acceptedValuePatterns);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a comma-delimited list of regular expressions to match
|
||||
* values of parameters that should be removed from the parameter map.
|
||||
*
|
||||
* @param commaDelimitedPatterns A comma-delimited set of regular expressions
|
||||
*/
|
||||
public void setExcludedValuePatterns(String commaDelimitedPatterns) {
|
||||
Set<String> patterns = TextParseUtil.commaDelimitedStringToSet(commaDelimitedPatterns);
|
||||
if (excludedValuePatterns == null) {
|
||||
// Limit unwanted log entries (for 1st call, excludedValuePatterns null)
|
||||
LOG.debug("Setting excluded value patterns to [{}]", patterns);
|
||||
} else {
|
||||
LOG.warn("Replacing excluded value patterns [{}] with [{}], be aware that this may impact safety of your application!",
|
||||
excludedValuePatterns, patterns);
|
||||
}
|
||||
excludedValuePatterns = new HashSet<>(patterns.size());
|
||||
try {
|
||||
for (String pattern : patterns) {
|
||||
excludedValuePatterns.add(Pattern.compile(pattern, Pattern.CASE_INSENSITIVE));
|
||||
}
|
||||
} finally {
|
||||
excludedValuePatterns = Collections.unmodifiableSet(excludedValuePatterns);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +82,9 @@ public class OgnlUtil {
|
||||
*/
|
||||
@Deprecated
|
||||
public OgnlUtil() {
|
||||
this(null, null); // Instantiate default Expression and BeanInfo caches (null factories)
|
||||
// Instantiate default Expression and BeanInfo caches (factories must be non-null).
|
||||
this(new DefaultOgnlExpressionCacheFactory<String, Object>(),
|
||||
new DefaultOgnlBeanInfoCacheFactory<Class<?>, BeanInfo>());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -96,10 +98,17 @@ public class OgnlUtil {
|
||||
* @param ognlExpressionCacheFactory factory for Expression cache instance. If null, it uses a default
|
||||
* @param ognlBeanInfoCacheFactory factory for BeanInfo cache instance. If null, it uses a default
|
||||
*/
|
||||
@Inject
|
||||
public OgnlUtil(
|
||||
@Inject(value = StrutsConstants.STRUTS_OGNL_EXPRESSION_CACHE_FACTORY, required = false) ExpressionCacheFactory<String, Object> ognlExpressionCacheFactory,
|
||||
@Inject(value = StrutsConstants.STRUTS_OGNL_BEANINFO_CACHE_FACTORY, required = false) BeanInfoCacheFactory<Class<?>, BeanInfo> ognlBeanInfoCacheFactory
|
||||
@Inject ExpressionCacheFactory<String, Object> ognlExpressionCacheFactory,
|
||||
@Inject BeanInfoCacheFactory<Class<?>, BeanInfo> ognlBeanInfoCacheFactory
|
||||
) {
|
||||
if (ognlExpressionCacheFactory == null) {
|
||||
throw new IllegalArgumentException("ExpressionCacheFactory parameter cannot be null");
|
||||
}
|
||||
if (ognlBeanInfoCacheFactory == null) {
|
||||
throw new IllegalArgumentException("BeanInfoCacheFactory parameter cannot be null");
|
||||
}
|
||||
excludedClasses = Collections.unmodifiableSet(new HashSet<>());
|
||||
excludedPackageNamePatterns = Collections.unmodifiableSet(new HashSet<>());
|
||||
excludedPackageNames = Collections.unmodifiableSet(new HashSet<>());
|
||||
@@ -108,11 +117,8 @@ public class OgnlUtil {
|
||||
devModeExcludedPackageNamePatterns = Collections.unmodifiableSet(new HashSet<>());
|
||||
devModeExcludedPackageNames = Collections.unmodifiableSet(new HashSet<>());
|
||||
|
||||
OgnlCacheFactory<String, Object> ognlExpressionCacheFactory1 = (ognlExpressionCacheFactory != null ? ognlExpressionCacheFactory : new DefaultOgnlExpressionCacheFactory<>());
|
||||
OgnlCacheFactory<Class<?>, BeanInfo> ognlBeanInfoCacheFactory1 = (ognlBeanInfoCacheFactory != null ? ognlBeanInfoCacheFactory : new DefaultOgnlBeanInfoCacheFactory<>());
|
||||
|
||||
this.expressionCache = ognlExpressionCacheFactory1.buildOgnlCache();
|
||||
this.beanInfoCache = ognlBeanInfoCacheFactory1.buildOgnlCache();
|
||||
this.expressionCache = ognlExpressionCacheFactory.buildOgnlCache();
|
||||
this.beanInfoCache = ognlBeanInfoCacheFactory.buildOgnlCache();
|
||||
}
|
||||
|
||||
@Inject
|
||||
@@ -262,10 +268,10 @@ public class OgnlUtil {
|
||||
try {
|
||||
if (maxLength == null || maxLength.isEmpty()) {
|
||||
Ognl.applyExpressionMaxLength(null);
|
||||
LOG.info("OGNL Expression Max Length disabled.");
|
||||
LOG.warn("OGNL Expression Max Length disabled.");
|
||||
} else {
|
||||
Ognl.applyExpressionMaxLength(Integer.parseInt(maxLength));
|
||||
LOG.info("OGNL Expression Max Length enabled with {}.", maxLength);
|
||||
LOG.debug("OGNL Expression Max Length enabled with {}.", maxLength);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
LOG.error("Unable to set OGNL Expression Max Length {}.", maxLength); // Help configuration debugging.
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ package com.opensymphony.xwork2.security;
|
||||
/**
|
||||
* Used across different places to check if given string is not excluded and is accepted
|
||||
* @see <a href="https://securitylab.github.com/research/apache-struts-double-evaluation/">here</a>
|
||||
* @since 2.6
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public interface NotExcludedAcceptedPatternsChecker extends ExcludedPatternsChecker, AcceptedPatternsChecker {
|
||||
|
||||
|
||||
@@ -235,7 +235,7 @@ abstract class AbstractLocalizedTextProvider implements LocalizedTextProvider {
|
||||
*
|
||||
* @param bundleName The bundle to remove from the bundle map
|
||||
*
|
||||
* @deprecated A "no-op" since 2.6. Use {@link #clearBundle(java.lang.String, java.util.Locale)} instead.
|
||||
* @deprecated A "no-op" since 6.0.0. Use {@link #clearBundle(java.lang.String, java.util.Locale)} instead.
|
||||
*/
|
||||
public void clearBundle(final String bundleName) {
|
||||
LOG.debug("No-op. Did NOT clear resource bundle [{}], result: false.", bundleName);
|
||||
@@ -248,7 +248,7 @@ abstract class AbstractLocalizedTextProvider implements LocalizedTextProvider {
|
||||
* @param bundleName The bundle (combined with locale) to remove from the bundle map
|
||||
* @param locale Provides the locale to combine with the bundle to get the key
|
||||
*
|
||||
* @since 2.6
|
||||
* @since 6.0.0
|
||||
*/
|
||||
protected void clearBundle(final String bundleName, Locale locale) {
|
||||
final String key = createMissesKey(String.valueOf(getCurrentThreadContextClassLoader().hashCode()), bundleName, locale);
|
||||
@@ -266,7 +266,7 @@ abstract class AbstractLocalizedTextProvider implements LocalizedTextProvider {
|
||||
* {@link AbstractLocalizedTextProvider} has already been used for failed bundle
|
||||
* lookups of a given key, or some transitory state made a bundle lookup fail.
|
||||
*
|
||||
* @since 2.6
|
||||
* @since 6.0.0
|
||||
*/
|
||||
protected void clearMissingBundlesCache() {
|
||||
missingBundles.clear();
|
||||
@@ -313,7 +313,7 @@ abstract class AbstractLocalizedTextProvider implements LocalizedTextProvider {
|
||||
* The <code>clearCache()</code> methods have been available since Java 1.6, so
|
||||
* it is anticipated the logic will work on any subsequent JVM versions.
|
||||
*
|
||||
* @since 2.6
|
||||
* @since 6.0.0
|
||||
*/
|
||||
private void clearResourceBundleClassloaderCaches() {
|
||||
final ClassLoader ccl = getCurrentThreadContextClassLoader();
|
||||
@@ -436,7 +436,7 @@ abstract class AbstractLocalizedTextProvider implements LocalizedTextProvider {
|
||||
*
|
||||
* @param searchDefaultBundlesFirst provide {@link String} "true" or "false" to set the flag state accordingly.
|
||||
*
|
||||
* @since 2.6
|
||||
* @since 6.0.0
|
||||
*/
|
||||
@Inject(value = StrutsConstants.STRUTS_I18N_SEARCH_DEFAULTBUNDLES_FIRST, required = false)
|
||||
public void setSearchDefaultBundlesFirst(String searchDefaultBundlesFirst) {
|
||||
|
||||
@@ -28,9 +28,17 @@ import org.apache.struts2.StrutsException;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.xml.sax.*;
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.ContentHandler;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.Locator;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.SAXNotRecognizedException;
|
||||
import org.xml.sax.SAXNotSupportedException;
|
||||
import org.xml.sax.SAXParseException;
|
||||
import org.xml.sax.helpers.DefaultHandler;
|
||||
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.parsers.SAXParser;
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
@@ -48,28 +56,24 @@ import java.util.Map;
|
||||
public class DomHelper {
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(DomHelper.class);
|
||||
|
||||
public static final String XMLNS_URI = "http://www.w3.org/2000/xmlns/";
|
||||
|
||||
public static Location getLocationObject(Element element) {
|
||||
return LocationAttributes.getLocation(element);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a W3C Document that remembers the location of each element in
|
||||
* the source file. The location of element nodes can then be retrieved
|
||||
* using the {@link #getLocationObject(Element)} method.
|
||||
*
|
||||
* @param inputSource the inputSource to read the document from
|
||||
*
|
||||
* @return the W3C Document
|
||||
*/
|
||||
public static Document parse(InputSource inputSource) {
|
||||
return parse(inputSource, null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates a W3C Document that remembers the location of each element in
|
||||
* the source file. The location of element nodes can then be retrieved
|
||||
@@ -77,17 +81,16 @@ public class DomHelper {
|
||||
*
|
||||
* @param inputSource the inputSource to read the document from
|
||||
* @param dtdMappings a map of DTD names and public ids
|
||||
*
|
||||
* @return the W3C Document
|
||||
*/
|
||||
public static Document parse(InputSource inputSource, Map<String, String> dtdMappings) {
|
||||
|
||||
|
||||
SAXParserFactory factory = null;
|
||||
String parserProp = System.getProperty("xwork.saxParserFactory");
|
||||
if (parserProp != null) {
|
||||
try {
|
||||
ObjectFactory objectFactory = ActionContext.getContext().getContainer().getInstance(ObjectFactory.class);
|
||||
Class clazz = objectFactory.getClassInstance(parserProp);
|
||||
Class<?> clazz = objectFactory.getClassInstance(parserProp);
|
||||
factory = (SAXParserFactory) clazz.newInstance();
|
||||
} catch (Exception e) {
|
||||
LOG.error("Unable to load saxParserFactory set by system property 'xwork.saxParserFactory': {}", parserProp, e);
|
||||
@@ -98,6 +101,13 @@ public class DomHelper {
|
||||
factory = SAXParserFactory.newInstance();
|
||||
}
|
||||
|
||||
try {
|
||||
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
|
||||
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
|
||||
} catch (ParserConfigurationException | SAXNotRecognizedException | SAXNotSupportedException e) {
|
||||
throw new StrutsException("Unable to disable resolving external entities!", e);
|
||||
}
|
||||
|
||||
factory.setValidating((dtdMappings != null));
|
||||
factory.setNamespaceAware(true);
|
||||
|
||||
@@ -107,22 +117,22 @@ public class DomHelper {
|
||||
} catch (Exception ex) {
|
||||
throw new StrutsException("Unable to create SAX parser", ex);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
DOMBuilder builder = new DOMBuilder();
|
||||
|
||||
// Enhance the sax stream with location information
|
||||
ContentHandler locationHandler = new LocationAttributes.Pipe(builder);
|
||||
|
||||
|
||||
try {
|
||||
parser.parse(inputSource, new StartHandler(locationHandler, dtdMappings));
|
||||
} catch (Exception ex) {
|
||||
throw new StrutsException(ex);
|
||||
}
|
||||
|
||||
|
||||
return builder.getDocument();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The <code>DOMBuilder</code> is a utility class that will generate a W3C
|
||||
* DOM Document from SAX events.
|
||||
@@ -130,27 +140,35 @@ public class DomHelper {
|
||||
* @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
|
||||
*/
|
||||
static public class DOMBuilder implements ContentHandler {
|
||||
|
||||
/** The default transformer factory shared by all instances */
|
||||
|
||||
/**
|
||||
* The default transformer factory shared by all instances
|
||||
*/
|
||||
protected static SAXTransformerFactory FACTORY;
|
||||
|
||||
/** The transformer factory */
|
||||
|
||||
/**
|
||||
* The transformer factory
|
||||
*/
|
||||
protected SAXTransformerFactory factory;
|
||||
|
||||
/** The result */
|
||||
|
||||
/**
|
||||
* The result
|
||||
*/
|
||||
protected DOMResult result;
|
||||
|
||||
/** The parentNode */
|
||||
|
||||
/**
|
||||
* The parentNode
|
||||
*/
|
||||
protected Node parentNode;
|
||||
|
||||
|
||||
protected ContentHandler nextHandler;
|
||||
|
||||
|
||||
static {
|
||||
String parserProp = System.getProperty("xwork.saxTransformerFactory");
|
||||
if (parserProp != null) {
|
||||
try {
|
||||
ObjectFactory objectFactory = ActionContext.getContext().getContainer().getInstance(ObjectFactory.class);
|
||||
Class clazz = objectFactory.getClassInstance(parserProp);
|
||||
Class<?> clazz = objectFactory.getClassInstance(parserProp);
|
||||
FACTORY = (SAXTransformerFactory) clazz.newInstance();
|
||||
} catch (Exception e) {
|
||||
LOG.error("Unable to load SAXTransformerFactory set by system property 'xwork.saxTransformerFactory': {}", parserProp, e);
|
||||
@@ -158,7 +176,7 @@ public class DomHelper {
|
||||
}
|
||||
|
||||
if (FACTORY == null) {
|
||||
FACTORY = (SAXTransformerFactory) TransformerFactory.newInstance();
|
||||
FACTORY = (SAXTransformerFactory) TransformerFactory.newInstance();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,15 +186,16 @@ public class DomHelper {
|
||||
public DOMBuilder() {
|
||||
this((Node) null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Construct a new instance of this DOMBuilder.
|
||||
*
|
||||
* @param factory the SAX transformer factory
|
||||
*/
|
||||
public DOMBuilder(SAXTransformerFactory factory) {
|
||||
this(factory, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new instance that appends nodes to the given parent node.
|
||||
*
|
||||
@@ -185,19 +204,19 @@ public class DomHelper {
|
||||
public DOMBuilder(Node parentNode) {
|
||||
this(null, parentNode);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Construct a new instance of this DOMBuilder.
|
||||
*
|
||||
* @param factory the SAX transformer factory
|
||||
* @param factory the SAX transformer factory
|
||||
* @param parentNode the parent node
|
||||
*/
|
||||
public DOMBuilder(SAXTransformerFactory factory, Node parentNode) {
|
||||
this.factory = factory == null? FACTORY: factory;
|
||||
this.factory = factory == null ? FACTORY : factory;
|
||||
this.parentNode = parentNode;
|
||||
setup();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Setup this instance transformer and result objects.
|
||||
*/
|
||||
@@ -215,7 +234,7 @@ public class DomHelper {
|
||||
throw new StrutsException("Fatal-Error: Unable to get transformer handler", local);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the newly built Document.
|
||||
*
|
||||
@@ -230,60 +249,61 @@ public class DomHelper {
|
||||
return this.result.getNode().getOwnerDocument();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setDocumentLocator(Locator locator) {
|
||||
nextHandler.setDocumentLocator(locator);
|
||||
}
|
||||
|
||||
|
||||
public void startDocument() throws SAXException {
|
||||
nextHandler.startDocument();
|
||||
}
|
||||
|
||||
|
||||
public void endDocument() throws SAXException {
|
||||
nextHandler.endDocument();
|
||||
}
|
||||
|
||||
|
||||
public void startElement(String uri, String loc, String raw, Attributes attrs) throws SAXException {
|
||||
nextHandler.startElement(uri, loc, raw, attrs);
|
||||
}
|
||||
|
||||
|
||||
public void endElement(String arg0, String arg1, String arg2) throws SAXException {
|
||||
nextHandler.endElement(arg0, arg1, arg2);
|
||||
}
|
||||
|
||||
|
||||
public void startPrefixMapping(String arg0, String arg1) throws SAXException {
|
||||
nextHandler.startPrefixMapping(arg0, arg1);
|
||||
}
|
||||
|
||||
|
||||
public void endPrefixMapping(String arg0) throws SAXException {
|
||||
nextHandler.endPrefixMapping(arg0);
|
||||
}
|
||||
|
||||
|
||||
public void characters(char[] arg0, int arg1, int arg2) throws SAXException {
|
||||
nextHandler.characters(arg0, arg1, arg2);
|
||||
}
|
||||
|
||||
|
||||
public void ignorableWhitespace(char[] arg0, int arg1, int arg2) throws SAXException {
|
||||
nextHandler.ignorableWhitespace(arg0, arg1, arg2);
|
||||
}
|
||||
|
||||
|
||||
public void processingInstruction(String arg0, String arg1) throws SAXException {
|
||||
nextHandler.processingInstruction(arg0, arg1);
|
||||
}
|
||||
|
||||
|
||||
public void skippedEntity(String arg0) throws SAXException {
|
||||
nextHandler.skippedEntity(arg0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class StartHandler extends DefaultHandler {
|
||||
|
||||
private ContentHandler nextHandler;
|
||||
private Map<String, String> dtdMappings;
|
||||
|
||||
|
||||
private final ContentHandler nextHandler;
|
||||
private final Map<String, String> dtdMappings;
|
||||
|
||||
/**
|
||||
* Create a filter that is chained to another handler.
|
||||
* @param next the next handler in the chain.
|
||||
*
|
||||
* @param next the next handler in the chain.
|
||||
* @param dtdMappings map of DTD mappings
|
||||
*/
|
||||
public StartHandler(ContentHandler next, Map<String, String> dtdMappings) {
|
||||
@@ -295,12 +315,12 @@ public class DomHelper {
|
||||
public void setDocumentLocator(Locator locator) {
|
||||
nextHandler.setDocumentLocator(locator);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void startDocument() throws SAXException {
|
||||
nextHandler.startDocument();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void endDocument() throws SAXException {
|
||||
nextHandler.endDocument();
|
||||
@@ -345,7 +365,7 @@ public class DomHelper {
|
||||
public void skippedEntity(String arg0) throws SAXException {
|
||||
nextHandler.skippedEntity(arg0);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public InputSource resolveEntity(String publicId, String systemId) {
|
||||
if (dtdMappings != null && dtdMappings.containsKey(publicId)) {
|
||||
@@ -356,7 +376,7 @@ public class DomHelper {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void warning(SAXParseException exception) {
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
*/
|
||||
package com.opensymphony.xwork2.util;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -57,7 +59,7 @@ import java.util.regex.Pattern;
|
||||
* </table>
|
||||
*
|
||||
* <p>
|
||||
* Excaping hasn't been implemented since the intended use of these patterns will be in matching URLs.
|
||||
* Escaping hasn't been implemented since the intended use of these patterns will be in matching URLs.
|
||||
* </p>
|
||||
*
|
||||
* @since 2.1
|
||||
@@ -75,38 +77,47 @@ public class NamedVariablePatternMatcher implements PatternMatcher<NamedVariable
|
||||
* @return The compiled pattern, null if the pattern was null or empty
|
||||
*/
|
||||
public CompiledPattern compilePattern(String data) {
|
||||
StringBuilder regex = new StringBuilder();
|
||||
if (data != null && data.length() > 0) {
|
||||
List<String> varNames = new ArrayList<>();
|
||||
StringBuilder varName = null;
|
||||
for (int x=0; x<data.length(); x++) {
|
||||
char c = data.charAt(x);
|
||||
switch (c) {
|
||||
case '{' : varName = new StringBuilder(); break;
|
||||
case '}' : if (varName == null) {
|
||||
throw new IllegalArgumentException("Mismatched braces in pattern");
|
||||
}
|
||||
varNames.add(varName.toString());
|
||||
regex.append("([^/]+)");
|
||||
varName = null;
|
||||
break;
|
||||
default : if (varName == null) {
|
||||
regex.append(c);
|
||||
} else {
|
||||
varName.append(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
return new CompiledPattern(Pattern.compile(regex.toString()), varNames);
|
||||
if (StringUtils.isEmpty(data)) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
|
||||
int len = data.length();
|
||||
StringBuilder regex = new StringBuilder();
|
||||
List<String> varNames = new ArrayList<>();
|
||||
int s = 0;
|
||||
while (s < len) {
|
||||
int e = data.indexOf('{', s);
|
||||
if (e < 0 && data.indexOf('}') > -1) {
|
||||
throw new IllegalArgumentException("Missing openning '{' in [" + data + "]!");
|
||||
}
|
||||
if (e < 0) {
|
||||
regex.append(Pattern.quote(data.substring(s)));
|
||||
break;
|
||||
}
|
||||
if (e > s) {
|
||||
regex.append(Pattern.quote(data.substring(s, e)));
|
||||
}
|
||||
s = e + 1;
|
||||
e = data.indexOf('}', s);
|
||||
if (e < 0) {
|
||||
return null;
|
||||
}
|
||||
String varName = data.substring(s, e);
|
||||
if (StringUtils.isEmpty(varName)) {
|
||||
throw new IllegalArgumentException("Missing variable name in [" + data + "]!");
|
||||
}
|
||||
varNames.add(varName);
|
||||
regex.append("([^/]+)");
|
||||
s = e + 1;
|
||||
}
|
||||
return new CompiledPattern(Pattern.compile(regex.toString()), varNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to process the data against the compiled expression. If successful, the map will contain
|
||||
* the matched data, using the specified variable names in the original pattern.
|
||||
*
|
||||
* @param map The map of variables
|
||||
* @param map The map of variables
|
||||
* @param data The data to match
|
||||
* @param expr The compiled pattern
|
||||
* @return True if matched, false if not matched, the data was null, or the data was an empty string
|
||||
@@ -116,8 +127,8 @@ public class NamedVariablePatternMatcher implements PatternMatcher<NamedVariable
|
||||
if (data != null && data.length() > 0) {
|
||||
Matcher matcher = expr.getPattern().matcher(data);
|
||||
if (matcher.matches()) {
|
||||
for (int x=0; x<expr.getVariableNames().size(); x++) {
|
||||
map.put(expr.getVariableNames().get(x), matcher.group(x+1));
|
||||
for (int x = 0; x < expr.getVariableNames().size(); x++) {
|
||||
map.put(expr.getVariableNames().get(x), matcher.group(x + 1));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -129,8 +140,8 @@ public class NamedVariablePatternMatcher implements PatternMatcher<NamedVariable
|
||||
* Stores the compiled pattern and the variable names matches will correspond to.
|
||||
*/
|
||||
public static class CompiledPattern {
|
||||
private Pattern pattern;
|
||||
private List<String> variableNames;
|
||||
private final Pattern pattern;
|
||||
private final List<String> variableNames;
|
||||
|
||||
|
||||
public CompiledPattern(Pattern pattern, List<String> variableNames) {
|
||||
|
||||
@@ -29,11 +29,11 @@ import java.util.List;
|
||||
/**
|
||||
* ClassFinder searches the classpath of the specified ClassLoaderInterface for
|
||||
* packages, classes, constructors, methods, or fields with specific annotations.
|
||||
*
|
||||
* <p>
|
||||
* For security reasons ASM is used to find the annotations. Classes are not
|
||||
* loaded unless they match the requirements of a called findAnnotated* method.
|
||||
* Once loaded, these classes are cached.
|
||||
*
|
||||
* <p>
|
||||
* The getClassesNotLoaded() method can be used immediately after any find*
|
||||
* method to get a list of classes which matched the find requirements (i.e.
|
||||
* contained the annotation), but were unable to be loaded.
|
||||
@@ -67,32 +67,32 @@ public interface ClassFinder {
|
||||
|
||||
List<Package> findAnnotatedPackages(Class<? extends Annotation> annotation);
|
||||
|
||||
List<Class> findAnnotatedClasses(Class<? extends Annotation> annotation);
|
||||
List<Class<?>> findAnnotatedClasses(Class<? extends Annotation> annotation);
|
||||
|
||||
List<Method> findAnnotatedMethods(Class<? extends Annotation> annotation);
|
||||
|
||||
List<Constructor> findAnnotatedConstructors(Class<? extends Annotation> annotation);
|
||||
List<Constructor<?>> findAnnotatedConstructors(Class<? extends Annotation> annotation);
|
||||
|
||||
List<Field> findAnnotatedFields(Class<? extends Annotation> annotation);
|
||||
|
||||
List<Class> findClassesInPackage(String packageName, boolean recursive);
|
||||
List<Class<?>> findClassesInPackage(String packageName, boolean recursive);
|
||||
|
||||
List<Class> findClasses(Test<ClassInfo> test);
|
||||
List<Class<?>> findClasses(Test<ClassInfo> test);
|
||||
|
||||
List<Class> findClasses();
|
||||
List<Class<?>> findClasses();
|
||||
|
||||
ClassLoaderInterface getClassLoaderInterface();
|
||||
|
||||
public static interface Info {
|
||||
interface Info {
|
||||
String getName();
|
||||
|
||||
List<AnnotationInfo> getAnnotations();
|
||||
}
|
||||
|
||||
public class AnnotationInfo extends Annotatable implements Info {
|
||||
class AnnotationInfo extends Annotatable implements Info {
|
||||
private final String name;
|
||||
|
||||
public AnnotationInfo(Annotation annotation){
|
||||
public AnnotationInfo(Annotation annotation) {
|
||||
this(annotation.getClass().getName());
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ public interface ClassFinder {
|
||||
}
|
||||
}
|
||||
|
||||
public class Annotatable {
|
||||
class Annotatable {
|
||||
private final List<AnnotationInfo> annotations = new ArrayList<>();
|
||||
|
||||
public Annotatable(AnnotatedElement element) {
|
||||
@@ -134,12 +134,12 @@ public interface ClassFinder {
|
||||
|
||||
}
|
||||
|
||||
public class PackageInfo extends Annotatable implements Info {
|
||||
class PackageInfo extends Annotatable implements Info {
|
||||
private final String name;
|
||||
private final ClassInfo info;
|
||||
private final Package pkg;
|
||||
|
||||
public PackageInfo(Package pkg){
|
||||
public PackageInfo(Package pkg) {
|
||||
super(pkg);
|
||||
this.pkg = pkg;
|
||||
this.name = pkg.getName();
|
||||
@@ -157,11 +157,11 @@ public interface ClassFinder {
|
||||
}
|
||||
|
||||
public Package get() throws ClassNotFoundException {
|
||||
return (pkg != null)?pkg:info.get().getPackage();
|
||||
return (pkg != null) ? pkg : info.get().getPackage();
|
||||
}
|
||||
}
|
||||
|
||||
public class ClassInfo extends Annotatable implements Info {
|
||||
class ClassInfo extends Annotatable implements Info {
|
||||
private final String name;
|
||||
private final List<MethodInfo> methods = new ArrayList<>();
|
||||
private final List<MethodInfo> constructors = new ArrayList<>();
|
||||
@@ -169,17 +169,18 @@ public interface ClassFinder {
|
||||
private final List<String> interfaces = new ArrayList<>();
|
||||
private final List<String> superInterfaces = new ArrayList<>();
|
||||
private final List<FieldInfo> fields = new ArrayList<>();
|
||||
private final ClassFinder classFinder;
|
||||
|
||||
private Class<?> clazz;
|
||||
private ClassFinder classFinder;
|
||||
private ClassNotFoundException notFound;
|
||||
|
||||
public ClassInfo(Class clazz, ClassFinder classFinder) {
|
||||
public ClassInfo(Class<?> clazz, ClassFinder classFinder) {
|
||||
super(clazz);
|
||||
this.clazz = clazz;
|
||||
this.classFinder = classFinder;
|
||||
this.name = clazz.getName();
|
||||
Class superclass = clazz.getSuperclass();
|
||||
this.superType = superclass != null ? superclass.getName(): null;
|
||||
Class<?> superclass = clazz.getSuperclass();
|
||||
this.superType = superclass != null ? superclass.getName() : null;
|
||||
}
|
||||
|
||||
public ClassInfo(String name, String superType, ClassFinder classFinder) {
|
||||
@@ -188,8 +189,8 @@ public interface ClassFinder {
|
||||
this.classFinder = classFinder;
|
||||
}
|
||||
|
||||
public String getPackageName(){
|
||||
return name.indexOf('.') > 0 ? name.substring(0, name.lastIndexOf('.')) : "" ;
|
||||
public String getPackageName() {
|
||||
return name.indexOf('.') > 0 ? name.substring(0, name.lastIndexOf('.')) : "";
|
||||
}
|
||||
|
||||
public List<MethodInfo> getConstructors() {
|
||||
@@ -220,7 +221,7 @@ public interface ClassFinder {
|
||||
return superType;
|
||||
}
|
||||
|
||||
public Class get() throws ClassNotFoundException {
|
||||
public Class<?> get() throws ClassNotFoundException {
|
||||
if (clazz != null) return clazz;
|
||||
if (notFound != null) throw notFound;
|
||||
try {
|
||||
@@ -239,20 +240,20 @@ public interface ClassFinder {
|
||||
}
|
||||
}
|
||||
|
||||
public class MethodInfo extends Annotatable implements Info {
|
||||
class MethodInfo extends Annotatable implements Info {
|
||||
private final ClassInfo declaringClass;
|
||||
private final String returnType;
|
||||
private final String name;
|
||||
private final List<List<AnnotationInfo>> parameterAnnotations = new ArrayList<>();
|
||||
|
||||
public MethodInfo(ClassInfo info, Constructor constructor){
|
||||
public MethodInfo(ClassInfo info, Constructor<?> constructor) {
|
||||
super(constructor);
|
||||
this.declaringClass = info;
|
||||
this.name = "<init>";
|
||||
this.returnType = Void.TYPE.getName();
|
||||
}
|
||||
|
||||
public MethodInfo(ClassInfo info, Method method){
|
||||
public MethodInfo(ClassInfo info, Method method) {
|
||||
super(method);
|
||||
this.declaringClass = info;
|
||||
this.name = method.getName();
|
||||
@@ -297,12 +298,12 @@ public interface ClassFinder {
|
||||
}
|
||||
}
|
||||
|
||||
public class FieldInfo extends Annotatable implements Info {
|
||||
class FieldInfo extends Annotatable implements Info {
|
||||
private final String name;
|
||||
private final String type;
|
||||
private final ClassInfo declaringClass;
|
||||
|
||||
public FieldInfo(ClassInfo info, Field field){
|
||||
public FieldInfo(ClassInfo info, Field field) {
|
||||
super(field);
|
||||
this.declaringClass = info;
|
||||
this.name = field.getName();
|
||||
|
||||
@@ -222,7 +222,7 @@ import com.opensymphony.xwork2.util.ValueStack;
|
||||
* <!-- START SNIPPET: exShortCircuitingValidators -->
|
||||
* <!DOCTYPE validators PUBLIC
|
||||
* "-//Apache Struts//XWork Validator 1.0.3//EN"
|
||||
* "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
|
||||
* "https://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
|
||||
* <validators>
|
||||
* <!-- Field Validators for email field -->
|
||||
* <field name="email">
|
||||
|
||||
@@ -115,7 +115,7 @@ package com.opensymphony.xwork2.validator;
|
||||
* <pre>
|
||||
* <!-- START SNIPPET: exValidationRules1 -->
|
||||
* <!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.3//EN"
|
||||
"http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
|
||||
"https://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
|
||||
* <validators>
|
||||
* <field name="bar">
|
||||
* <field-validator type="required">
|
||||
|
||||
@@ -43,7 +43,7 @@ public final class StrutsConstants {
|
||||
* Note: This control flag may not be meaningful to all provider implementations, and should be false by default.
|
||||
* </p>
|
||||
*
|
||||
* @since 2.6
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public static final String STRUTS_I18N_SEARCH_DEFAULTBUNDLES_FIRST = "struts.i18n.search.defaultbundles.first";
|
||||
|
||||
@@ -56,6 +56,9 @@ public final class StrutsConstants {
|
||||
/** Comma separated list of patterns (java.util.regex.Pattern) to be excluded from Struts2-processing */
|
||||
public static final String STRUTS_ACTION_EXCLUDE_PATTERN = "struts.action.excludePattern";
|
||||
|
||||
/** A custom separator used to split list of patterns (java.util.regex.Pattern) to be excluded from Struts2-processing */
|
||||
public static final String STRUTS_ACTION_EXCLUDE_PATTERN_SEPARATOR = "struts.action.excludePattern.separator";
|
||||
|
||||
/** Whether to use the response encoding (JSP page encoding) for s:include tag processing (false - use STRUTS_I18N_ENCODING - by default) */
|
||||
public static final String STRUTS_TAG_INCLUDETAG_USERESPONSEENCODING = "struts.tag.includetag.useResponseEncoding";
|
||||
|
||||
@@ -139,6 +142,9 @@ public final class StrutsConstants {
|
||||
/** The maximize size of a multipart request (file upload) */
|
||||
public static final String STRUTS_MULTIPART_MAXSIZE = "struts.multipart.maxSize";
|
||||
|
||||
/** The maximized number of files allowed to upload */
|
||||
public static final String STRUTS_MULTIPART_MAXFILES = "struts.multipart.maxFiles";
|
||||
|
||||
/** The directory to use for storing uploaded files */
|
||||
public static final String STRUTS_MULTIPART_SAVEDIR = "struts.multipart.saveDir";
|
||||
|
||||
@@ -254,7 +260,7 @@ public final class StrutsConstants {
|
||||
* Specifies an OGNL expression cache factory implementation. A default implementation is provided, but
|
||||
* could be replaced by a custom one if desired.
|
||||
*
|
||||
* @since 2.6
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public static final String STRUTS_OGNL_EXPRESSION_CACHE_FACTORY = "struts.ognl.expressionCacheFactory";
|
||||
|
||||
@@ -262,7 +268,7 @@ public final class StrutsConstants {
|
||||
* Specifies an OGNL BeanInfo cache factory implementation. A default implementation is provided, but
|
||||
* could be replaced by a custom one if desired.
|
||||
*
|
||||
* @since 2.6
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public static final String STRUTS_OGNL_BEANINFO_CACHE_FACTORY = "struts.ognl.beanInfoCacheFactory";
|
||||
|
||||
@@ -275,7 +281,7 @@ public final class StrutsConstants {
|
||||
* For the optional LRU cache, once the maximum is reached, the least-recently-used (LRU) entry will be
|
||||
* removed when a new entry needs to be added (cache is fully-utilized).
|
||||
*
|
||||
* @since 2.6
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public static final String STRUTS_OGNL_BEANINFO_CACHE_MAXSIZE = "struts.ognl.beanInfoCacheMaxSize";
|
||||
|
||||
@@ -287,32 +293,32 @@ public final class StrutsConstants {
|
||||
* Note: When enabling LRU cache mode you must also set a maximum size (via {@link #STRUTS_OGNL_BEANINFO_CACHE_MAXSIZE})
|
||||
* for it to be effective. Otherwise, there is no condition to evict a LRU entry (cache has no limit).
|
||||
*
|
||||
* @since 2.6
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public static final String STRUTS_OGNL_BEANINFO_CACHE_LRU_MODE = "struts.ognl.beanInfoCacheLRUMode";
|
||||
|
||||
/**
|
||||
* Logs properties that are not found (very verbose)
|
||||
* @since 2.6
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public static final String STRUTS_OGNL_LOG_MISSING_PROPERTIES = "struts.ognl.logMissingProperties";
|
||||
|
||||
/**
|
||||
* Logs properties that are not found (very verbose)
|
||||
* @deprecated as of 2.6. Use {@link #STRUTS_OGNL_LOG_MISSING_PROPERTIES} instead.
|
||||
* @deprecated as of 6.0.0. Use {@link #STRUTS_OGNL_LOG_MISSING_PROPERTIES} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String STRUTS_LOG_MISSING_PROPERTIES = STRUTS_OGNL_LOG_MISSING_PROPERTIES;
|
||||
|
||||
/**
|
||||
* Enables caching of parsed OGNL expressions
|
||||
* @since 2.6
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public static final String STRUTS_OGNL_ENABLE_EXPRESSION_CACHE = "struts.ognl.enableExpressionCache";
|
||||
|
||||
/**
|
||||
* Enables caching of parsed OGNL expressions
|
||||
* @deprecated as of 2.6. Use {@link #STRUTS_OGNL_ENABLE_EXPRESSION_CACHE} instead.
|
||||
* @deprecated as of 6.0.0. Use {@link #STRUTS_OGNL_ENABLE_EXPRESSION_CACHE} instead.
|
||||
*/
|
||||
public static final String STRUTS_ENABLE_OGNL_EXPRESSION_CACHE = STRUTS_OGNL_ENABLE_EXPRESSION_CACHE;
|
||||
|
||||
@@ -325,7 +331,7 @@ public final class StrutsConstants {
|
||||
* For the optional LRU cache, once the maximum is reached, the least-recently-used (LRU) entry will be
|
||||
* removed when a new entry needs to be added (cache is fully-utilized).
|
||||
*
|
||||
* @since 2.6
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public static final String STRUTS_OGNL_EXPRESSION_CACHE_MAXSIZE = "struts.ognl.expressionCacheMaxSize";
|
||||
|
||||
@@ -337,19 +343,19 @@ public final class StrutsConstants {
|
||||
* Note: When enabling LRU cache mode you must also set a maximum size (via {@link #STRUTS_OGNL_EXPRESSION_CACHE_MAXSIZE})
|
||||
* for it to be effective. Otherwise, there is no condition to evict a LRU entry (cache has no limit).
|
||||
*
|
||||
* @since 2.6
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public static final String STRUTS_OGNL_EXPRESSION_CACHE_LRU_MODE = "struts.ognl.expressionCacheLRUMode";
|
||||
|
||||
/**
|
||||
* Enables evaluation of OGNL expressions
|
||||
* @since 2.6
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public static final String STRUTS_OGNL_ENABLE_EVAL_EXPRESSION = "struts.ognl.enableEvalExpression";
|
||||
|
||||
/**
|
||||
* Enables evaluation of OGNL expressions
|
||||
* @deprecated as of 2.6. Use {@link #STRUTS_OGNL_ENABLE_EVAL_EXPRESSION} instead.
|
||||
* @deprecated as of 6.0.0. Use {@link #STRUTS_OGNL_ENABLE_EVAL_EXPRESSION} instead.
|
||||
*/
|
||||
public static final String STRUTS_ENABLE_OGNL_EVAL_EXPRESSION = STRUTS_OGNL_ENABLE_EVAL_EXPRESSION;
|
||||
|
||||
@@ -376,7 +382,7 @@ public final class StrutsConstants {
|
||||
public static final String STRUTS_CONVERTER_FILE_PROCESSOR = "struts.converter.file.processor";
|
||||
public static final String STRUTS_CONVERTER_ANNOTATION_PROCESSOR = "struts.converter.annotation.processor";
|
||||
public static final String STRUTS_CONVERTER_CREATOR = "struts.converter.creator";
|
||||
public static final String STRUTS_CONVERTER_HOLDER = "struts..converter.holder";
|
||||
public static final String STRUTS_CONVERTER_HOLDER = "struts.converter.holder";
|
||||
|
||||
public static final String STRUTS_EXPRESSION_PARSER = "struts.expression.parser";
|
||||
|
||||
@@ -398,7 +404,11 @@ public final class StrutsConstants {
|
||||
/** Enables action: prefix */
|
||||
public static final String STRUTS_MAPPER_ACTION_PREFIX_ENABLED = "struts.mapper.action.prefix.enabled";
|
||||
|
||||
/** Enables access to actions in other namespaces than current with action: prefix */
|
||||
/**
|
||||
* Enables access to actions in other namespaces than current with action: prefix
|
||||
* @deprecated it will be removed soon, please refactor your application
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String STRUTS_MAPPER_ACTION_PREFIX_CROSSNAMESPACES = "struts.mapper.action.prefix.crossNamespaces";
|
||||
|
||||
public static final String DEFAULT_TEMPLATE_TYPE_CONFIG_KEY = "struts.ui.templateSuffix";
|
||||
@@ -450,4 +460,12 @@ public final class StrutsConstants {
|
||||
|
||||
/** See {@link org.apache.struts2.components.Date#setDateFormatter(DateFormatter)} */
|
||||
public static final String STRUTS_DATE_FORMATTER = "struts.date.formatter";
|
||||
|
||||
public static final String STRUTS_URL_QUERY_STRING_BUILDER = "struts.url.queryStringBuilder";
|
||||
public static final String STRUTS_URL_QUERY_STRING_PARSER = "struts.url.queryStringParser";
|
||||
public static final String STRUTS_URL_ENCODER = "struts.url.encoder";
|
||||
public static final String STRUTS_URL_DECODER = "struts.url.decoder";
|
||||
|
||||
/** A global flag to set property {@link org.apache.struts2.components.Checkbox#setSubmitUnchecked(String)} */
|
||||
public static final String STRUTS_UI_CHECKBOX_SUBMIT_UNCHECKED = "struts.ui.checkbox.submitUnchecked";
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ import java.util.Map;
|
||||
* Please note that the {@link CookieInterceptor} needs to be
|
||||
* activated to receive a cookies map.
|
||||
*
|
||||
* @since 2.6
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public interface CookiesAware {
|
||||
/**
|
||||
@@ -37,4 +37,4 @@ public interface CookiesAware {
|
||||
* @param cookies the cookies
|
||||
*/
|
||||
void withCookies(Map<String, String> cookies);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ import org.apache.struts2.dispatcher.HttpParameters;
|
||||
* One common use for this is to have the action propagate parameters to internally instantiated data
|
||||
* objects.
|
||||
*
|
||||
* @since 2.6
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public interface ParametersAware {
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ import javax.servlet.ServletContext;
|
||||
/**
|
||||
* For components that have a dependence on the Servlet context.
|
||||
*
|
||||
* @since 2.6
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public interface ServletContextAware {
|
||||
|
||||
|
||||
@@ -18,13 +18,14 @@
|
||||
*/
|
||||
package org.apache.struts2.components;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import com.opensymphony.xwork2.util.ValueStack;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
import org.apache.struts2.views.annotations.StrutsTag;
|
||||
import org.apache.struts2.views.annotations.StrutsTagAttribute;
|
||||
|
||||
import com.opensymphony.xwork2.util.ValueStack;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* <!-- START SNIPPET: javadoc -->
|
||||
@@ -46,15 +47,19 @@ import com.opensymphony.xwork2.util.ValueStack;
|
||||
*
|
||||
* <!-- END SNIPPET: example -->
|
||||
* </pre>
|
||||
*
|
||||
*/
|
||||
@StrutsTag(
|
||||
name="checkbox",
|
||||
tldTagClass="org.apache.struts2.views.jsp.ui.CheckboxTag",
|
||||
description="Render a checkbox input field",
|
||||
allowDynamicAttributes=true)
|
||||
name = "checkbox",
|
||||
tldTagClass = "org.apache.struts2.views.jsp.ui.CheckboxTag",
|
||||
description = "Render a checkbox input field",
|
||||
allowDynamicAttributes = true)
|
||||
public class Checkbox extends UIBean {
|
||||
final public static String TEMPLATE = "checkbox";
|
||||
|
||||
private static final String ATTR_SUBMIT_UNCHECKED = "submitUnchecked";
|
||||
|
||||
public static final String TEMPLATE = "checkbox";
|
||||
|
||||
private String submitUncheckedGlobal;
|
||||
|
||||
protected String fieldValue;
|
||||
protected String submitUnchecked;
|
||||
@@ -69,46 +74,45 @@ public class Checkbox extends UIBean {
|
||||
|
||||
protected void evaluateExtraParams() {
|
||||
if (fieldValue != null) {
|
||||
addParameter("fieldValue", findString(fieldValue));
|
||||
addParameter(ATTR_FIELD_VALUE, findString(fieldValue));
|
||||
} else {
|
||||
addParameter("fieldValue", "true");
|
||||
addParameter(ATTR_FIELD_VALUE, "true");
|
||||
}
|
||||
|
||||
if (submitUnchecked != null) {
|
||||
Object parsedValue = findValue(submitUnchecked, Boolean.class);
|
||||
addParameter("submitUnchecked", parsedValue == null ? Boolean.valueOf(submitUnchecked) : parsedValue);
|
||||
addParameter(ATTR_SUBMIT_UNCHECKED, parsedValue == null ? Boolean.valueOf(submitUnchecked) : parsedValue);
|
||||
} else if (submitUncheckedGlobal != null) {
|
||||
addParameter(ATTR_SUBMIT_UNCHECKED, Boolean.parseBoolean(submitUncheckedGlobal));
|
||||
} else {
|
||||
addParameter("submitUnchecked", false);
|
||||
addParameter(ATTR_SUBMIT_UNCHECKED, false);
|
||||
}
|
||||
}
|
||||
|
||||
protected Class getValueClassType() {
|
||||
@Override
|
||||
protected Class<?> getValueClassType() {
|
||||
return Boolean.class; // for checkboxes, everything needs to end up as a Boolean
|
||||
}
|
||||
|
||||
@StrutsTagAttribute(description="The actual HTML value attribute of the checkbox.", defaultValue="true")
|
||||
@Inject(value = StrutsConstants.STRUTS_UI_CHECKBOX_SUBMIT_UNCHECKED, required = false)
|
||||
public void setSubmitUncheckedGlobal(String submitUncheckedGlobal) {
|
||||
this.submitUncheckedGlobal = submitUncheckedGlobal;
|
||||
}
|
||||
|
||||
@StrutsTagAttribute(description = "The actual HTML value attribute of the checkbox.", defaultValue = "true")
|
||||
public void setFieldValue(String fieldValue) {
|
||||
this.fieldValue = fieldValue;
|
||||
}
|
||||
|
||||
@StrutsTagAttribute(description="If set to true, unchecked elements will be submitted with the form.", type="Boolean", defaultValue="false")
|
||||
@StrutsTagAttribute(description = "If set to true, unchecked elements will be submitted with the form. " +
|
||||
"Since Struts 6.1.1 you can use a constant \"" + StrutsConstants.STRUTS_UI_CHECKBOX_SUBMIT_UNCHECKED + "\" to set this attribute globally",
|
||||
type = "Boolean", defaultValue = "false")
|
||||
public void setSubmitUnchecked(String submitUnchecked) {
|
||||
this.submitUnchecked = submitUnchecked;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated since 2.5.27
|
||||
* @deprecated use {@link #setLabelPosition(String)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
@Override
|
||||
@StrutsTagAttribute(description="(Deprecated) Define label position of form element (top/left), also 'right' is supported when using 'xhtml' theme")
|
||||
public void setLabelposition(String labelPosition) {
|
||||
super.setLabelPosition(labelPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
@StrutsTagAttribute(description="Define label position of form element (top/left), also 'right' is supported when using 'xhtml' theme")
|
||||
@StrutsTagAttribute(description = "Define label position of form element (top/left), also 'right' is supported when using 'xhtml' theme")
|
||||
public void setLabelPosition(String labelPosition) {
|
||||
super.setLabelPosition(labelPosition);
|
||||
}
|
||||
|
||||
@@ -538,7 +538,7 @@ public class Component {
|
||||
* Override to set if body content should be HTML-escaped.
|
||||
*
|
||||
* @return always true (default) for this component.
|
||||
* @since 2.6
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public boolean escapeHtmlBody() {
|
||||
return escapeHtmlBody;
|
||||
@@ -600,7 +600,7 @@ public class Component {
|
||||
*
|
||||
* @param expression of the component
|
||||
* @return true|false
|
||||
* @since 2.6
|
||||
* @since 6.0.0
|
||||
*/
|
||||
protected boolean isAcceptableExpression(String expression) {
|
||||
NotExcludedAcceptedPatternsChecker.IsAllowed isAllowed = notExcludedAcceptedPatterns.isAllowed(expression);
|
||||
|
||||
@@ -59,7 +59,7 @@ import java.util.List;
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* <b>Note</b>: Since Struts 2.6 a new Java 8 API has been used to format the Date, it's based on
|
||||
* <b>Note</b>: Since Struts 6.0.0 a new Java 8 API has been used to format the Date, it's based on
|
||||
* <a href="https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html">DateTimeFormatter</a>
|
||||
* which uses a bit different patterns.
|
||||
* </p>
|
||||
@@ -293,7 +293,9 @@ public class Date extends ContextBean {
|
||||
final ZoneId tz = getTimeZone();
|
||||
// find the name on the valueStack
|
||||
Object dateObject = findValue(name);
|
||||
if (dateObject instanceof java.util.Date) {
|
||||
if (dateObject instanceof java.sql.Date) {
|
||||
date = ((java.sql.Date) dateObject).toLocalDate().atStartOfDay(tz);
|
||||
} else if (dateObject instanceof java.util.Date) {
|
||||
date = ((java.util.Date) dateObject).toInstant().atZone(tz);
|
||||
} else if (dateObject instanceof Calendar) {
|
||||
date = ((Calendar) dateObject).toInstant().atZone(tz);
|
||||
|
||||
@@ -21,5 +21,7 @@ package org.apache.struts2.components;
|
||||
import java.util.Map;
|
||||
|
||||
public interface ExtraParameterProvider {
|
||||
public Map getExtraParameters();
|
||||
|
||||
Map<String, Object> getExtraParameters();
|
||||
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user