mirror of
https://github.com/apache/struts.git
synced 2026-08-09 08:36:54 +00:00
Compare commits
213 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4cf9093cc5 | |||
| 46bae3ce68 | |||
| dfa8fb3e4c | |||
| a2df8f9890 | |||
| 7253edeada | |||
| 2efe3cec7a | |||
| 4506d5716d | |||
| 83aff6e470 | |||
| 3138dc7fbd | |||
| 4566734662 | |||
| d591b7e3b9 | |||
| 9c45d6b025 | |||
| 482af41673 | |||
| 0a75d8e8fa | |||
| 1d18e8f9a8 | |||
| f6365e7363 | |||
| 84aeb77011 | |||
| b3a9d82d58 | |||
| 828d02fcbd | |||
| 88b05cdaed | |||
| e60df05c27 | |||
| 1efcc938cf | |||
| 7b1c3b0fca | |||
| 10a834a54c | |||
| abb1ac3c99 | |||
| dcc59937a8 | |||
| 22c88faf38 | |||
| 1191ca3ed0 | |||
| bcfb769005 | |||
| d61be3e4ce | |||
| c7149ab1bc | |||
| 4504e610f1 | |||
| 9b3a23eb28 | |||
| 3220d832d2 | |||
| bd007953ea | |||
| 1b0c743e85 | |||
| 89e02a4fb4 | |||
| 8cb93ad39a | |||
| e8656d5737 | |||
| 7f10ed505f | |||
| 043814b774 | |||
| 0fabde9f97 | |||
| 4457f03c70 | |||
| 3d3512a399 | |||
| 59a6cbf6ca | |||
| 19802b0614 | |||
| e46e662a7a | |||
| 4786fba0d7 | |||
| e32bd7dba9 | |||
| 6e1d2add07 | |||
| 2eeac367fe | |||
| 30b43044a3 | |||
| 5c82f0246e | |||
| fff35cfd9d | |||
| 1526b36dd6 | |||
| 6d6a422db7 | |||
| 5cf57b9132 | |||
| f4c0135878 | |||
| 77cfae3084 | |||
| ec56290056 | |||
| 47c87bc62c | |||
| ce467b7fa5 | |||
| 73eb6ed189 | |||
| 80a91dc75f | |||
| a6edb0d5df | |||
| 3dfc5a4074 | |||
| fdfeb3233a | |||
| ae3ae2be76 | |||
| 8dface4fcb | |||
| 1348971d40 | |||
| dd6d206d78 | |||
| e2b644a4fb | |||
| 13cfba86f8 | |||
| d84d59f53c | |||
| 3651f55869 | |||
| 7ffa750c68 | |||
| 313876aa3c | |||
| 9d7a9f81db | |||
| fe98223724 | |||
| 1de94b2092 | |||
| 706bb560e4 | |||
| 12d4feaf8f | |||
| d88a8382d4 | |||
| 73809eae54 | |||
| 5b4b554d11 | |||
| fcbd29b7f9 | |||
| 220896a0cf | |||
| 632f19eab3 | |||
| 50a145152d | |||
| f7b191f782 | |||
| 4ae1a6a26d | |||
| 79e598f360 | |||
| 9216e8e22c | |||
| 651eac2c57 | |||
| a50af87644 | |||
| 9e01fbd2dd | |||
| d4dd3386cc | |||
| 0999fba8c4 | |||
| 3ac6835c5c | |||
| b0dd7c1c0d | |||
| a63beef1f8 | |||
| e74e5539dd | |||
| 2226fcc168 | |||
| 865b8a20df | |||
| 3c6956116e | |||
| bb9ce7582b | |||
| 11d373f8b4 | |||
| b23bfd42d2 | |||
| f94b681050 | |||
| fb38a919c9 | |||
| e25c826167 | |||
| 4815744eaf | |||
| f5a7776854 | |||
| f45d2752bb | |||
| 0262574095 | |||
| 30cb56a414 | |||
| 63dc85fd7a | |||
| 5b0ec3400d | |||
| d460d71498 | |||
| 53f64cdecf | |||
| aff4d46835 | |||
| a15c12a051 | |||
| e62155c460 | |||
| f7f4fbd47f | |||
| 2d81439553 | |||
| 7afe35cb96 | |||
| fdd1054070 | |||
| 32e88d1a2e | |||
| 6403de4516 | |||
| 13c517fc3c | |||
| 7242a87165 | |||
| 0323795d67 | |||
| 71267a9b4b | |||
| 5524c579d2 | |||
| 873ca8fa20 | |||
| 8988d57644 | |||
| 2e7cf63964 | |||
| 3eb68be674 | |||
| c9f279ec2e | |||
| 881e1b2580 | |||
| cb0ac7c440 | |||
| 96c38b27e4 | |||
| e9108f0feb | |||
| 3653f6e9e1 | |||
| 5a2323a19f | |||
| ea09a8828b | |||
| 17fe42c0f7 | |||
| 87fa5bddf2 | |||
| 45161e88f9 | |||
| 4456620b51 | |||
| f4a8f42ca4 | |||
| a6f8895c90 | |||
| 46dbdbe018 | |||
| 6f176cc5a7 | |||
| db085dbeef | |||
| c3205888b4 | |||
| ce9789c4c9 | |||
| b431755332 | |||
| c694c6fdfb | |||
| 1d49a06272 | |||
| 264e03b7ed | |||
| 2f99110189 | |||
| d33930f3bd | |||
| 360927931c | |||
| bff033e6a3 | |||
| 536d2db4b8 | |||
| 32c8f6f811 | |||
| 06e5dfc2ab | |||
| fe630db5f2 | |||
| b75c0ba5e1 | |||
| 8ab102209f | |||
| d7a7c909ea | |||
| 24e151143e | |||
| c5272d2a0d | |||
| 11de8810e4 | |||
| 75dc4c00d2 | |||
| 415ce3e165 | |||
| fe6257b995 | |||
| 3b81a9edaa | |||
| 478a9b8f1c | |||
| 12c3d23bdf | |||
| 8293add6aa | |||
| ecb7beef38 | |||
| bac0f2953c | |||
| 7bca98205d | |||
| 567fae9dfc | |||
| f4d7dbe88e | |||
| 289782c583 | |||
| 1e33df947a | |||
| de1a42d34a | |||
| b816cc1374 | |||
| b802baa4a9 | |||
| daac47ee62 | |||
| b1709c5208 | |||
| daf6f6f749 | |||
| 029892d656 | |||
| 65fb0d4a44 | |||
| 58d87025e9 | |||
| 83c0f1cd1e | |||
| eacc002334 | |||
| 45effc3822 | |||
| bad9a49060 | |||
| a75eddb515 | |||
| 6e87474f9a | |||
| 9fcbd912bc | |||
| fbc780e779 | |||
| 6eb83016e3 | |||
| 3ec7fa9d80 | |||
| f9806ee4e1 | |||
| d175836757 | |||
| e55ad3fb45 | |||
| 6efaf900d4 | |||
| b3bad5ea44 |
@@ -1,14 +0,0 @@
|
||||
# Documentation https://s.apache.org/asfyaml
|
||||
notifications:
|
||||
commits: commits@struts.apache.org
|
||||
# Send all issue emails (new, closed, comments) to issues@
|
||||
issues: issues@struts.apache.org
|
||||
# Send new/closed PR notifications to dev@
|
||||
pullrequests_status: dev@struts.apache.org
|
||||
# Send individual PR comments/reviews to issues@
|
||||
pullrequests_comment: issues@struts.apache.org
|
||||
# Link opened PRs with JIRA
|
||||
jira_options: link label worklog
|
||||
|
||||
github:
|
||||
del_branch_on_merge: true
|
||||
+37
-20
@@ -11,9 +11,6 @@
|
||||
.metadata/
|
||||
Servers/
|
||||
|
||||
# Java annotation processor (APT)
|
||||
.factorypath
|
||||
|
||||
#VSCode
|
||||
.vscode
|
||||
|
||||
@@ -27,22 +24,42 @@ Servers/
|
||||
.java-version
|
||||
|
||||
# Maven
|
||||
target/
|
||||
pom.xml.tag
|
||||
pom.xml.releaseBackup
|
||||
pom.xml.versionsBackup
|
||||
pom.xml.next
|
||||
release.properties
|
||||
dependency-reduced-pom.xml
|
||||
buildNumber.properties
|
||||
.mvn/timing.properties
|
||||
.mvn/wrapper/maven-wrapper.jar
|
||||
|
||||
core/target
|
||||
plugins/convention/target
|
||||
plugins/embeddedjsp/target
|
||||
plugins/osgi/target
|
||||
plugins/cdi/target
|
||||
plugins/spring/target
|
||||
plugins/jfreechart/target
|
||||
apps/rest-showcase/target
|
||||
apps/mailreader/target
|
||||
apps/portlet/target
|
||||
apps/blank/target
|
||||
apps/jboss-blank/target
|
||||
apps/mailreader/target
|
||||
apps/portlet/target
|
||||
apps/showcase/target
|
||||
apps/target
|
||||
bundles/admin/target
|
||||
plugins/config-browser/target
|
||||
plugins/jasperreports/target
|
||||
plugins/json/target
|
||||
plugins/portlet-tiles/target
|
||||
plugins/portlet/target
|
||||
plugins/sitegraph/target
|
||||
plugins/sitemesh/target
|
||||
plugins/javatemplates/target
|
||||
bundles/demo/target
|
||||
plugins/rest/target
|
||||
plugins/plexus/target
|
||||
plugins/testng/target
|
||||
plugins/dwr/target
|
||||
plugins/gxp/target
|
||||
plugins/oval/target
|
||||
plugins/junit/target
|
||||
plugins/tiles/target
|
||||
bundles/target
|
||||
plugins/target
|
||||
target
|
||||
plugins/testng/test-output
|
||||
test-output
|
||||
|
||||
# Sonar
|
||||
/.sonar/
|
||||
|
||||
# Tidelift CLI scanner
|
||||
.tidelift
|
||||
|
||||
+22
-29
@@ -1,18 +1,22 @@
|
||||
/*
|
||||
* Copyright 2007-present the original author or authors.
|
||||
*
|
||||
* Licensed 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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
|
||||
import java.net.*;
|
||||
import java.io.*;
|
||||
import java.nio.channels.*;
|
||||
@@ -20,12 +24,11 @@ import java.util.Properties;
|
||||
|
||||
public class MavenWrapperDownloader {
|
||||
|
||||
private static final String WRAPPER_VERSION = "0.5.6";
|
||||
/**
|
||||
* Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
|
||||
*/
|
||||
private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
|
||||
+ WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
|
||||
private static final String DEFAULT_DOWNLOAD_URL =
|
||||
"https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.0/maven-wrapper-0.4.0.jar";
|
||||
|
||||
/**
|
||||
* Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
|
||||
@@ -73,13 +76,13 @@ public class MavenWrapperDownloader {
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println("- Downloading from: " + url);
|
||||
System.out.println("- Downloading from: : " + url);
|
||||
|
||||
File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
|
||||
if(!outputFile.getParentFile().exists()) {
|
||||
if(!outputFile.getParentFile().mkdirs()) {
|
||||
System.out.println(
|
||||
"- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
|
||||
"- ERROR creating output direcrory '" + outputFile.getParentFile().getAbsolutePath() + "'");
|
||||
}
|
||||
}
|
||||
System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
|
||||
@@ -95,16 +98,6 @@ public class MavenWrapperDownloader {
|
||||
}
|
||||
|
||||
private static void downloadFileFromURL(String urlString, File destination) throws Exception {
|
||||
if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
|
||||
String username = System.getenv("MVNW_USERNAME");
|
||||
char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
|
||||
Authenticator.setDefault(new Authenticator() {
|
||||
@Override
|
||||
protected PasswordAuthentication getPasswordAuthentication() {
|
||||
return new PasswordAuthentication(username, password);
|
||||
}
|
||||
});
|
||||
}
|
||||
URL website = new URL(urlString);
|
||||
ReadableByteChannel rbc;
|
||||
rbc = Channels.newChannel(website.openStream());
|
||||
|
||||
BIN
Binary file not shown.
+1
-18
@@ -1,18 +1 @@
|
||||
# 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.
|
||||
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
|
||||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.5.3/apache-maven-3.5.3-bin.zip
|
||||
+18
-18
@@ -1,29 +1,29 @@
|
||||
dist: jammy
|
||||
dist: trusty
|
||||
language: java
|
||||
sudo: false
|
||||
|
||||
jdk:
|
||||
- openjdk11
|
||||
- openjdk17
|
||||
- openjdk7
|
||||
- oraclejdk8
|
||||
- oraclejdk9
|
||||
- oraclejdk11
|
||||
|
||||
install: true
|
||||
script: mvn test -DskipAssembly -B
|
||||
|
||||
after_success:
|
||||
# TODO delete following if statement after fix of https://github.com/cobertura/cobertura/issues/271
|
||||
- if [ "$TRAVIS_JDK_VERSION" == "openjdk8" ] || [ "$TRAVIS_JDK_VERSION" == "oraclejdk8" ]; then
|
||||
mvn cobertura:cobertura org.eluder.coveralls:coveralls-maven-plugin:report com.updateimpact:updateimpact-maven-plugin:submit -Ptravis-coveralls,update-impact -DskipAssembly -B;
|
||||
else
|
||||
echo "Not reporting coverage for $TRAVIS_JDK_VERSION due to incompatibility or to save performance";
|
||||
fi;
|
||||
|
||||
env:
|
||||
global:
|
||||
- secure: iI7IpfDtS+LUyS2yNuRCR3KelNyvBHuoMQ3gb1UNmR5SSL7jO/p3olQWrQROs28FJ+dpE3lHyIjoHrebKQGJHHAgTG2XWxn+G3fDsf+wSSFSLoDGj0o2SgGXooBbR2dccnNZHCyQaOyE2cIPWaOxrQZFE4No70LQB4mrP/gdkoc=
|
||||
matrix:
|
||||
include:
|
||||
- jdk: openjdk8
|
||||
env: STRUTS_IT=true # do integration tests and coverage reports when jdk 11 and 17 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;
|
||||
global:
|
||||
secure: DusDFL9cuX+mj64tXQfrYVbUVYnxlXmad4nuIMj0/lgDbwJ6kxYasJmR99bdvwu08gS9D5b7a+m7WJTN0FNATzEiiGDXcM+TiDPlYDh7dcalU4QGiLmMuCCEw1r7hp2XE4BWVgDfFhCsHhStgjE4RXzHIyPowoPXr4ugPf8at6w=
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.m2
|
||||
- $HOME/.m2
|
||||
|
||||
|
||||
Vendored
+14
-241
@@ -1,255 +1,28 @@
|
||||
#!groovy
|
||||
|
||||
pipeline {
|
||||
agent none
|
||||
agent {
|
||||
label 'ubuntu'
|
||||
}
|
||||
options {
|
||||
buildDiscarder logRotator(daysToKeepStr: '14', numToKeepStr: '10')
|
||||
timeout(80)
|
||||
disableConcurrentBuilds()
|
||||
skipStagesAfterUnstable()
|
||||
quietPeriod(30)
|
||||
}
|
||||
tools {
|
||||
jdk 'jdk_1.7_latest'
|
||||
maven 'maven_3_latest'
|
||||
}
|
||||
triggers {
|
||||
pollSCM 'H/15 * * * *'
|
||||
}
|
||||
stages {
|
||||
stage('Prepare') {
|
||||
agent {
|
||||
label 'ubuntu'
|
||||
}
|
||||
stages {
|
||||
stage('Clean up') {
|
||||
steps {
|
||||
cleanWs deleteDirs: true, patterns: [[pattern: '**/target/**', type: 'INCLUDE']]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('JDK 17') {
|
||||
agent {
|
||||
label 'ubuntu'
|
||||
}
|
||||
tools {
|
||||
jdk 'jdk_17_latest'
|
||||
maven 'maven_3_latest'
|
||||
}
|
||||
environment {
|
||||
MAVEN_OPTS = "-Xmx1024m"
|
||||
}
|
||||
stages {
|
||||
stage('Build') {
|
||||
steps {
|
||||
sh './mvnw -B clean install -DskipTests -DskipAssembly'
|
||||
}
|
||||
}
|
||||
stage('Test') {
|
||||
steps {
|
||||
sh './mvnw -B test'
|
||||
}
|
||||
post {
|
||||
always {
|
||||
junit(testResults: '**/surefire-reports/*.xml', allowEmptyResults: true)
|
||||
junit(testResults: '**/failsafe-reports/*.xml', allowEmptyResults: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
post {
|
||||
always {
|
||||
cleanWs deleteDirs: true, patterns: [[pattern: '**/target/**', type: 'INCLUDE']]
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('JDK 11') {
|
||||
agent {
|
||||
label 'ubuntu'
|
||||
}
|
||||
tools {
|
||||
jdk 'jdk_11_latest'
|
||||
maven 'maven_3_latest'
|
||||
}
|
||||
environment {
|
||||
MAVEN_OPTS = "-Xmx1024m"
|
||||
}
|
||||
stages {
|
||||
stage('Build') {
|
||||
steps {
|
||||
sh './mvnw -B clean install -DskipTests -DskipAssembly'
|
||||
}
|
||||
}
|
||||
stage('Test') {
|
||||
steps {
|
||||
sh './mvnw -B test'
|
||||
}
|
||||
post {
|
||||
always {
|
||||
junit(testResults: '**/surefire-reports/*.xml', allowEmptyResults: true)
|
||||
junit(testResults: '**/failsafe-reports/*.xml', allowEmptyResults: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Code Quality') {
|
||||
when {
|
||||
branch 'master'
|
||||
}
|
||||
steps {
|
||||
withCredentials([string(credentialsId: 'asf-struts-sonarcloud', variable: 'SONARCLOUD_TOKEN')]) {
|
||||
sh './mvnw sonar:sonar -DskipAssembly -Dsonar.login=${SONARCLOUD_TOKEN}'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
post {
|
||||
always {
|
||||
cleanWs deleteDirs: true, patterns: [[pattern: '**/target/**', type: 'INCLUDE']]
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('JDK 8') {
|
||||
agent {
|
||||
label 'ubuntu'
|
||||
}
|
||||
tools {
|
||||
jdk 'jdk_1.8_latest'
|
||||
maven 'maven_3_latest'
|
||||
}
|
||||
environment {
|
||||
MAVEN_OPTS = "-Xmx1024m"
|
||||
}
|
||||
stages {
|
||||
stage('Build') {
|
||||
steps {
|
||||
sh './mvnw -B clean install -DskipTests -DskipAssembly'
|
||||
}
|
||||
}
|
||||
stage('Test') {
|
||||
steps {
|
||||
sh './mvnw -B test'
|
||||
// step([$class: 'JiraIssueUpdater', issueSelector: [$class: 'DefaultIssueSelector'], scm: scm])
|
||||
}
|
||||
post {
|
||||
always {
|
||||
junit(testResults: '**/surefire-reports/*.xml', allowEmptyResults: true)
|
||||
junit(testResults: '**/failsafe-reports/*.xml', allowEmptyResults: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Build Source & JavaDoc') {
|
||||
when {
|
||||
branch 'master'
|
||||
}
|
||||
steps {
|
||||
dir("local-snapshots-dir/") {
|
||||
deleteDir()
|
||||
}
|
||||
sh './mvnw -B source:jar javadoc:jar -DskipTests -DskipAssembly'
|
||||
}
|
||||
}
|
||||
stage('Deploy Snapshot') {
|
||||
when {
|
||||
branch 'master'
|
||||
}
|
||||
steps {
|
||||
withCredentials([file(credentialsId: 'lukaszlenart-repository-access-token', variable: 'CUSTOM_SETTINGS')]) {
|
||||
sh './mvnw -s \${CUSTOM_SETTINGS} deploy -DskipTests -DskipAssembly'
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Upload nightlies') {
|
||||
when {
|
||||
branch 'master'
|
||||
}
|
||||
steps {
|
||||
sshPublisher(publishers: [
|
||||
sshPublisherDesc(
|
||||
configName: 'Nightlies',
|
||||
transfers: [
|
||||
sshTransfer(
|
||||
remoteDirectory: '/struts/snapshot',
|
||||
removePrefix: 'assembly/target/assembly/out',
|
||||
sourceFiles: 'assembly/target/assembly/out/struts-*.zip'
|
||||
)
|
||||
],
|
||||
verbose: true
|
||||
)
|
||||
])
|
||||
}
|
||||
}
|
||||
}
|
||||
post {
|
||||
always {
|
||||
cleanWs deleteDirs: true, patterns: [[pattern: '**/target/**', type: 'INCLUDE']]
|
||||
}
|
||||
}
|
||||
}
|
||||
environment {
|
||||
MAVEN_OPTS = '-Xmx1024m -XX:MaxPermSize=256m'
|
||||
}
|
||||
post {
|
||||
// If this build failed, send an email to the list.
|
||||
failure {
|
||||
script {
|
||||
emailext(
|
||||
to: "dev@struts.apache.org",
|
||||
recipientProviders: [[$class: 'DevelopersRecipientProvider']],
|
||||
from: "Mr. Jenkins <jenkins@builds.apache.org>",
|
||||
subject: "Jenkins job ${env.JOB_NAME}#${env.BUILD_NUMBER} failed",
|
||||
body: """
|
||||
There is a build failure in ${env.JOB_NAME}.
|
||||
|
||||
Build: ${env.BUILD_URL}
|
||||
Logs: ${env.BUILD_URL}console
|
||||
Changes: ${env.BUILD_URL}changes
|
||||
|
||||
--
|
||||
Mr. Jenkins
|
||||
Director of Continuous Integration
|
||||
"""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// If this build didn't fail, but there were failing tests, send an email to the list.
|
||||
unstable {
|
||||
script {
|
||||
emailext(
|
||||
to: "dev@struts.apache.org",
|
||||
recipientProviders: [[$class: 'DevelopersRecipientProvider']],
|
||||
from: "Mr. Jenkins <jenkins@builds.apache.org>",
|
||||
subject: "Jenkins job ${env.JOB_NAME}#${env.BUILD_NUMBER} unstable",
|
||||
body: """
|
||||
Some tests have failed in ${env.JOB_NAME}.
|
||||
|
||||
Build: ${env.BUILD_URL}
|
||||
Logs: ${env.BUILD_URL}console
|
||||
Changes: ${env.BUILD_URL}changes
|
||||
|
||||
--
|
||||
Mr. Jenkins
|
||||
Director of Continuous Integration
|
||||
"""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Send an email, if the last build was not successful and this one is.
|
||||
fixed {
|
||||
script {
|
||||
emailext(
|
||||
to: "dev@struts.apache.org",
|
||||
recipientProviders: [[$class: 'DevelopersRecipientProvider']],
|
||||
from: 'Mr. Jenkins <jenkins@builds.apache.org>',
|
||||
subject: "Jenkins job ${env.JOB_NAME}#${env.BUILD_NUMBER} back to normal",
|
||||
body: """
|
||||
The build for ${env.JOB_NAME} completed successfully and is back to normal.
|
||||
|
||||
Build: ${env.BUILD_URL}
|
||||
Logs: ${env.BUILD_URL}console
|
||||
Changes: ${env.BUILD_URL}changes
|
||||
|
||||
--
|
||||
Mr. Jenkins
|
||||
Director of Continuous Integration
|
||||
"""
|
||||
)
|
||||
stages {
|
||||
stage('Build') {
|
||||
steps {
|
||||
sh 'mvn --version'
|
||||
sh 'mvn clean source:jar javadoc:jar install deploy -DskipWiki -Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,20 +17,20 @@
|
||||
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://builds.apache.org/view/S-Z/view/Struts/job/Struts-master-JDK7/)
|
||||
[](https://travis-ci.org/apache/struts)
|
||||
[](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://app.updateimpact.com/latest/713283867011846144/Struts%202)
|
||||
[](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.
|
||||
|
||||
## Documentation
|
||||
|
||||
More information can be found on the [homepage](https://struts.apache.org/). Please read the [Security Guide](https://struts.apache.org/security/),
|
||||
More information can be found on the [homepage](https://struts.apache.org/). Please read the [Security Guide](https://struts.apache.org/security/)
|
||||
and the [JavaDocs](https://struts.apache.org/maven/struts2-core/apidocs/index.html) can be browsed.
|
||||
Questions related to the usage of Apache Struts should be posted to the [user mailing list](https://struts.apache.org/mail.html).
|
||||
Questions related to the usage of the Apache Struts should be posted to the [user mailing list](https://struts.apache.org/mail.html).
|
||||
|
||||
## Description
|
||||
|
||||
@@ -43,15 +43,13 @@ In practice, we find that unless these concerns are separated, larger applicatio
|
||||
One way to separate concerns in a software application is to use a Model-View-Controller (MVC) architecture. The Model
|
||||
represents the business or database code, the View represents the page design code, and the Controller represents
|
||||
the navigational code. The Struts framework is designed to help developers create web applications that utilize
|
||||
an MVC architecture.
|
||||
a MVC architecture.
|
||||
|
||||
The framework provides three key components:
|
||||
|
||||
- A “request” handler provided by the application developer that is mapped to a standard URI.
|
||||
- A “response” handler that transfers control to another resource which completes the response.
|
||||
- A tag library that helps developers create interactive form-based applications with server pages.
|
||||
|
||||
The framework’s architecture and tags are buzzword compliant. Struts works well
|
||||
A “request” handler provided by the application developer that is mapped to a standard URI. A “response” handler that
|
||||
transfers control to another resource which completes the response. A tag library that helps developers create interactive
|
||||
form-based applications with server pages. The framework’s architecture and tags are buzzword compliant. Struts works well
|
||||
with conventional REST applications and with technologies like SOAP and AJAX.
|
||||
|
||||
## The Apache Struts Project
|
||||
@@ -67,7 +65,7 @@ platform into a coherent whole. Our goal is to leverage existing standards by pr
|
||||
enterprise-grade applications that are easy to maintain over time.
|
||||
|
||||
The Apache Struts Project offered two major versions of the Struts framework. Currently we are only maintaining the Struts 2
|
||||
version. It is recommended to upgrade all Struts 1.x applications to Struts 2. Please do not start new application development
|
||||
version. It is recommended to upgrade all Struts 1.x application to Struts 2. Please do not start new application development
|
||||
using Struts 1.x, as we are no longer issuing security patches.
|
||||
|
||||
Struts 2 was originally known as WebWork 2. After working independently for several years, the WebWork and Struts
|
||||
@@ -76,33 +74,25 @@ to difficult problems.
|
||||
|
||||
## Why should you use Apache Struts?
|
||||
|
||||
Apache Struts is a modern, maintained and full-featured web framework. As it has been around for years and grown a huge user
|
||||
base it is unlikely it will go away anytime soon. Not only that, we have dedicated users and developers
|
||||
on the project. Apache Struts is licensed under the Apache License 2.0 and this will not change. We maintain a clean IP
|
||||
Apache Struts is a modern, maintained and full-featured web framework. It has been there for years and give the huge user
|
||||
base it is unlikely it will go away anytime soon in the future. Not only that we have dedicated users and developers
|
||||
on the project. Apache Struts is licensed to the Apache License 2.0 and this will not change. We maintain a clean IP
|
||||
and you are “safe” to use the project. Sometimes you are not “safe” to use a project when a company controls the SCM.
|
||||
Access to Source Code doesn’t mean it is free. With Apache Struts, you are not only free to “do what you want with it”,
|
||||
you can even contribute (which is not always the case). And best of all: you can become a part of the core team too.
|
||||
you can even contribute (which is not always the case). And best of it: you can become a part of the core team too.
|
||||
|
||||
It is usually very easy to integrate other technologies with Apache Struts. If you are using an ORM like Apache Cayenne,
|
||||
Hibernate or JDBC, you will not have any restrictions. Apache Struts is not even tied too much to a frontend technology.
|
||||
Hibernate or JDBC you will not have any restrictions. Apache Struts is not even tied too much to a frontend technology.
|
||||
In old days it was JSP, then came Velocity and Freemarker. Nowadays you might build your web application with just static
|
||||
HTML and AngularJS. Or you might want to use Sitemesh or Tiles. This all is no problem due to Struts' elegant and easy-to-use
|
||||
HTML and AngularJS. Or you want to use Sitemesh or Tiles. This all is no problem due to Struts elegant and easy to use
|
||||
extension mechanisms.
|
||||
|
||||
Unlike other, component-oriented frameworks, we do not aim to hide the stateless nature of the web. We think it is
|
||||
Unlike other, component oriented frameworks, we do not aim to hide the stateless nature of the web. We think it is
|
||||
perfectly acceptable to build upon a Request/Response cycle. We also think the MVC pattern is not so bad, just because
|
||||
it is old. In fact, we believe the Apache Struts architecture is clean and easy to understand.
|
||||
|
||||
Of course, if you wish to build components on the server side which render on the front end side, you will most likely
|
||||
not want Struts. This is a different approach which promises to reduce the amount of HTML/JavaScript knowledge needed
|
||||
Of course, if you wish to build components on the server side which render on the front end side, you are most likely
|
||||
wrong with Struts. This is a different approach which promises to reduce the amount of HTML/JavaScript knowledge needed
|
||||
and to create reusable components for the view layer. Projects like Wicket and Tapestry serve this purpose very well.
|
||||
As with every framework, you need to decide if it makes sense for you to build components or if you prefer
|
||||
the Struts approach.
|
||||
|
||||
## Commercial Support
|
||||
|
||||
The Apache Struts community does not offer commercial support by itself.
|
||||
|
||||
Some Apache Struts maintainers are working with [Tidelift](https://tidelift.com/) to provide commercial support and
|
||||
invest paid working time in the improvement of the Apache Struts framework. For more information, visit
|
||||
the [Tidelift resources regarding Apache Struts](https://tidelift.com/subscription/pkg/maven-org-apache-struts-struts2-core?utm_source=maven-org-apache-struts-struts2-core&utm_medium=referral&utm_campaign=readme)
|
||||
As with every framework you need to decide if it makes sense for you to build components or if you are better with
|
||||
the Struts-approach.
|
||||
|
||||
-39
@@ -1,39 +0,0 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
Please vist the [Releases](https://struts.apache.org/releases.html#prior-releases) page to see full information about each version
|
||||
and what potential vulnerability it can have:
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| 2.5.20 | :white_check_mark: |
|
||||
| 2.3.37 | :white_check_mark: |
|
||||
|
||||
## Reporting New Security Issues with thr Apache Struts
|
||||
|
||||
([original](https://struts.apache.org/security.html))
|
||||
|
||||
The Apache Struts project takes a very active stance in eliminating security problems
|
||||
and denial of service attacks against applications using the Apache Struts framework.
|
||||
|
||||
**We strongly encourage folks to report such security problems to our private security mailing list first,
|
||||
before disclosing them in a public forum**.
|
||||
|
||||
We cannot accept regular bug reports or other queries at this address, we ask that you use our
|
||||
[issue tracker (JIRA)](https://issues.apache.org/jira/browse/WW) for those.
|
||||
|
||||
```
|
||||
All mail sent to this address that does not relate to security problems in the Apache Struts source code will be ignored
|
||||
```
|
||||
|
||||
Note that all networked servers are subject to denial of service attacks, and we cannot promise magic
|
||||
workarounds to generic problems (such as a client streaming lots of data to your server, or re-requesting
|
||||
the same URL repeatedly). In general our philosophy is to avoid any attacks which can cause the server
|
||||
to consume resources in a non-linear relationship to the size of inputs.
|
||||
|
||||
The mailing address is: [security@struts.apache.org](mailto:security@struts.apache.org)
|
||||
|
||||
[General network server security tips](http://httpd.apache.org/docs/trunk/misc/security_tips.html)
|
||||
|
||||
[The Apache Security Team](http://www.apache.org/security/)
|
||||
+1
-1
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-parent</artifactId>
|
||||
<version>6.0.3</version>
|
||||
<version>2.5.26</version>
|
||||
</parent>
|
||||
<artifactId>struts2-apps</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
+15
-15
@@ -24,12 +24,12 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-apps</artifactId>
|
||||
<version>6.0.3</version>
|
||||
<version>2.5.26</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-rest-showcase</artifactId>
|
||||
<packaging>war</packaging>
|
||||
<version>6.0.3</version>
|
||||
<version>2.5.26</version>
|
||||
<name>Struts 2 Rest Showcase Webapp</name>
|
||||
<description>Struts 2 Rest Showcase Example</description>
|
||||
|
||||
@@ -73,32 +73,26 @@
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.jwebunit</groupId>
|
||||
<artifactId>jwebunit-core</artifactId>
|
||||
<version>3.3</version>
|
||||
<version>1.4.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.htmlunit</groupId>
|
||||
<artifactId>htmlunit</artifactId>
|
||||
<version>2.39.0</version>
|
||||
<groupId>commons-httpclient</groupId>
|
||||
<artifactId>commons-httpclient</artifactId>
|
||||
<version>3.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.jwebunit</groupId>
|
||||
<artifactId>jwebunit-htmlunit-plugin</artifactId>
|
||||
<version>3.3</version>
|
||||
<version>1.4.1</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>xom</groupId>
|
||||
<artifactId>xom</artifactId>
|
||||
</exclusion>
|
||||
<!-- not necessary to compile and it force dependency convergence issues -->
|
||||
<exclusion>
|
||||
<groupId>net.sourceforge.htmlunit</groupId>
|
||||
<artifactId>htmlunit</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
@@ -108,12 +102,18 @@
|
||||
<finalName>struts2-rest-showcase</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<groupId>org.mortbay.jetty</groupId>
|
||||
<artifactId>jetty-maven-plugin</artifactId>
|
||||
<version>9.4.46.v20220331</version>
|
||||
<version>8.1.16.v20140903</version>
|
||||
<configuration>
|
||||
<stopKey>CTRL+C</stopKey>
|
||||
<stopPort>8999</stopPort>
|
||||
<systemProperties>
|
||||
<systemProperty>
|
||||
<name>xwork.loggerFactory</name>
|
||||
<value>com.opensymphony.xwork2.util.logging.log4j2.Log4j2LoggerFactory</value>
|
||||
</systemProperty>
|
||||
</systemProperties>
|
||||
<scanIntervalSeconds>10</scanIntervalSeconds>
|
||||
<webAppSourceDirectory>${basedir}/src/main/webapp/</webAppSourceDirectory>
|
||||
<webAppConfig>
|
||||
|
||||
@@ -27,16 +27,14 @@
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Orders</title>
|
||||
<!-- Using a standard HTML link tag with JSP EL to get the contextPath may be simpler, but this is an equivalent for s:link -->
|
||||
<s:set var="pageContextPath"><%=((HttpServletRequest)request).getContextPath()%></s:set>
|
||||
<s:link href="%{#pageContextPath}/css/bootstrap.min.css" rel="stylesheet"></s:link>
|
||||
<s:link href="%{#pageContextPath}/css/app.css" rel="stylesheet"></s:link>
|
||||
<link href="${pageContext.request.contextPath}/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="${pageContext.request.contextPath}/css/app.css" rel="stylesheet">
|
||||
|
||||
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
|
||||
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
|
||||
<!--[if lt IE 9]>
|
||||
<s:script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></s:script>
|
||||
<s:script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></s:script>
|
||||
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
|
||||
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -27,16 +27,14 @@
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Orders</title>
|
||||
<!-- Using a standard HTML link tag with JSP EL to get the contextPath may be simpler, but this is an equivalent for s:link -->
|
||||
<s:set var="pageContextPath"><%=((HttpServletRequest)request).getContextPath()%></s:set>
|
||||
<s:link href="%{#pageContextPath}/css/bootstrap.min.css" rel="stylesheet"></s:link>
|
||||
<s:link href="%{#pageContextPath}/css/app.css" rel="stylesheet"></s:link>
|
||||
<link href="${pageContext.request.contextPath}/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="${pageContext.request.contextPath}/css/app.css" rel="stylesheet">
|
||||
|
||||
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
|
||||
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
|
||||
<!--[if lt IE 9]>
|
||||
<s:script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></s:script>
|
||||
<s:script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></s:script>
|
||||
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
|
||||
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -27,16 +27,13 @@
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Orders</title>
|
||||
<!-- Using a standard HTML link tag with JSP EL to get the contextPath may be simpler, but this is an equivalent for s:link -->
|
||||
<s:set var="pageContextPath"><%=((HttpServletRequest)request).getContextPath()%></s:set>
|
||||
<s:link href="%{#pageContextPath}/css/bootstrap.min.css" rel="stylesheet"></s:link>
|
||||
<s:link href="%{#pageContextPath}/css/app.css" rel="stylesheet"></s:link>
|
||||
|
||||
<link href="${pageContext.request.contextPath}/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="${pageContext.request.contextPath}/css/app.css" rel="stylesheet">
|
||||
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
|
||||
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
|
||||
<!--[if lt IE 9]>
|
||||
<s:script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></s:script>
|
||||
<s:script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></s:script>
|
||||
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
|
||||
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -27,16 +27,14 @@
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Orders</title>
|
||||
<!-- Using a standard HTML link tag with JSP EL to get the contextPath may be simpler, but this is an equivalent for s:link -->
|
||||
<s:set var="pageContextPath"><%=((HttpServletRequest)request).getContextPath()%></s:set>
|
||||
<s:link href="%{#pageContextPath}/css/bootstrap.min.css" rel="stylesheet"></s:link>
|
||||
<s:link href="%{#pageContextPath}/css/app.css" rel="stylesheet"></s:link>
|
||||
<link href="${pageContext.request.contextPath}/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="${pageContext.request.contextPath}/css/app.css" rel="stylesheet">
|
||||
|
||||
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
|
||||
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
|
||||
<!--[if lt IE 9]>
|
||||
<s:script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></s:script>
|
||||
<s:script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></s:script>
|
||||
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
|
||||
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -27,16 +27,14 @@
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Orders</title>
|
||||
<!-- Using a standard HTML link tag with JSP EL to get the contextPath may be simpler, but this is an equivalent for s:link -->
|
||||
<s:set var="pageContextPath"><%=((HttpServletRequest)request).getContextPath()%></s:set>
|
||||
<s:link href="%{#pageContextPath}/css/bootstrap.min.css" rel="stylesheet"></s:link>
|
||||
<s:link href="%{#pageContextPath}/css/app.css" rel="stylesheet"></s:link>
|
||||
<link href="${pageContext.request.contextPath}/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="${pageContext.request.contextPath}/css/app.css" rel="stylesheet">
|
||||
|
||||
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
|
||||
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
|
||||
<!--[if lt IE 9]>
|
||||
<s:script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></s:script>
|
||||
<s:script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></s:script>
|
||||
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
|
||||
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -19,16 +19,16 @@
|
||||
* under the License.
|
||||
*/
|
||||
-->
|
||||
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||
<web-app id="starter" version="2.4"
|
||||
xmlns="http://java.sun.com/xml/ns/j2ee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
|
||||
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
|
||||
version="3.1">
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
|
||||
|
||||
<display-name>Struts 2 Rest Example</display-name>
|
||||
<display-name>Struts 2 Rest Example</display-name>
|
||||
|
||||
<!-- Filters -->
|
||||
<!-- START SNIPPET: filter -->
|
||||
|
||||
<!-- Filters -->
|
||||
<!-- START SNIPPET: filter -->
|
||||
<filter>
|
||||
<filter-name>action2</filter-name>
|
||||
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
|
||||
|
||||
+59
-42
@@ -18,16 +18,15 @@
|
||||
*/
|
||||
package it.org.apache.struts2.rest.example;
|
||||
|
||||
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
|
||||
import net.sourceforge.jwebunit.junit.WebTestCase;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.apache.commons.httpclient.HttpClient;
|
||||
import org.apache.commons.httpclient.methods.PostMethod;
|
||||
import org.apache.commons.httpclient.methods.StringRequestEntity;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
|
||||
|
||||
public class PostOrderTest extends WebTestCase {
|
||||
|
||||
public void setUp() throws Exception {
|
||||
@@ -73,50 +72,68 @@ public class PostOrderTest extends WebTestCase {
|
||||
}
|
||||
|
||||
public void testPostOrderInXml() throws IOException {
|
||||
CloseableHttpClient client = HttpClients.createDefault();
|
||||
HttpPost httpPost = new HttpPost(ParameterUtils.getBaseUrl() + "/orders.xml");
|
||||
httpPost.setEntity(new StringEntity("<org.apache.struts2.rest.example.Order>\n" +
|
||||
"<clientName>Test3</clientName>\n" +
|
||||
"<amount>3342</amount>\n" +
|
||||
"</org.apache.struts2.rest.example.Order>"));
|
||||
CloseableHttpResponse response = client.execute(httpPost);
|
||||
assertEquals(201, response.getStatusLine().getStatusCode());
|
||||
assertTrue(response.getHeaders("Location")[0].getValue().startsWith(ParameterUtils.getBaseUrl() + "/orders/"));
|
||||
client.close();
|
||||
HttpClient client = new HttpClient();
|
||||
PostMethod method = null;
|
||||
try {
|
||||
method = new PostMethod(ParameterUtils.getBaseUrl()+"/orders.xml");
|
||||
method.setRequestEntity(new StringRequestEntity("<org.apache.struts2.rest.example.Order>\n" +
|
||||
"<clientName>Test3</clientName>\n" +
|
||||
"<amount>3342</amount>\n" +
|
||||
"</org.apache.struts2.rest.example.Order>"));
|
||||
client.executeMethod(method);
|
||||
assertEquals(201, method.getStatusCode());
|
||||
assertTrue(method.getResponseHeader("Location").getValue().startsWith(ParameterUtils.getBaseUrl()+"/orders/"));
|
||||
} finally {
|
||||
method.releaseConnection();
|
||||
}
|
||||
}
|
||||
|
||||
public void testPostOrderInXmlWithBadData() throws IOException {
|
||||
CloseableHttpClient client = HttpClients.createDefault();
|
||||
HttpPost httpPost = new HttpPost(ParameterUtils.getBaseUrl() + "/orders.xml");
|
||||
httpPost.setEntity(new StringEntity("<org.apache.struts2.rest.example.Order>\n" +
|
||||
"<amount>3342</amount>\n" +
|
||||
"</org.apache.struts2.rest.example.Order>"));
|
||||
CloseableHttpResponse response = client.execute(httpPost);
|
||||
assertEquals(400, response.getStatusLine().getStatusCode());
|
||||
assertTrue(response.toString().contains("<string>The client name is empty"));
|
||||
assertNull(response.getHeaders("Location"));
|
||||
client.close();
|
||||
HttpClient client = new HttpClient();
|
||||
PostMethod method = null;
|
||||
try {
|
||||
method = new PostMethod(ParameterUtils.getBaseUrl()+"/orders.xml");
|
||||
method.setRequestEntity(new StringRequestEntity("<org.apache.struts2.rest.example.Order>\n" +
|
||||
"<amount>3342</amount>\n" +
|
||||
"</org.apache.struts2.rest.example.Order>"));
|
||||
client.executeMethod(method);
|
||||
assertEquals(400, method.getStatusCode());
|
||||
String response = method.getResponseBodyAsString();
|
||||
assertTrue(response.contains("<string>The client name is empty"));
|
||||
assertNull(method.getResponseHeader("Location"));
|
||||
} finally {
|
||||
method.releaseConnection();
|
||||
}
|
||||
}
|
||||
|
||||
public void testPostOrderInJson() throws IOException {
|
||||
CloseableHttpClient client = HttpClients.createDefault();
|
||||
HttpPost httpPost = new HttpPost(ParameterUtils.getBaseUrl() + "/orders.json");
|
||||
httpPost.setEntity(new StringEntity("{\"amount\":33,\"clientName\":\"Test4\"}"));
|
||||
CloseableHttpResponse response = client.execute(httpPost);
|
||||
assertEquals(201, response.getStatusLine().getStatusCode());
|
||||
assertTrue(response.getHeaders("Location")[0].getValue().startsWith(ParameterUtils.getBaseUrl() + "/orders/"));
|
||||
client.close();
|
||||
HttpClient client = new HttpClient();
|
||||
PostMethod method = null;
|
||||
try {
|
||||
method = new PostMethod(ParameterUtils.getBaseUrl()+"/orders.json");
|
||||
method.setRequestEntity(new StringRequestEntity("{\"amount\":33,\"clientName\":\"Test4\"}"));
|
||||
client.executeMethod(method);
|
||||
assertEquals(201, method.getStatusCode());
|
||||
assertTrue(method.getResponseHeader("Location").getValue().startsWith(ParameterUtils.getBaseUrl()+"/orders/"));
|
||||
} finally {
|
||||
method.releaseConnection();
|
||||
}
|
||||
}
|
||||
|
||||
public void testPostOrderInJsonWithBadData() throws IOException {
|
||||
CloseableHttpClient client = HttpClients.createDefault();
|
||||
HttpPost httpPost = new HttpPost(ParameterUtils.getBaseUrl() + "/orders.json");
|
||||
httpPost.setEntity(new StringEntity("{\"amount\":33}"));
|
||||
CloseableHttpResponse response = client.execute(httpPost);
|
||||
assertEquals(400, response.getStatusLine().getStatusCode());
|
||||
assertTrue(response.toString()
|
||||
.contains("{\"actionErrors\":[],\"fieldErrors\":{\"clientName\":[\"The client name is empty\"]}}"));
|
||||
assertNull(response.getHeaders("Location"));
|
||||
client.close();
|
||||
HttpClient client = new HttpClient();
|
||||
PostMethod method = null;
|
||||
try {
|
||||
method = new PostMethod(ParameterUtils.getBaseUrl()+"/orders.json");
|
||||
method.setRequestEntity(new StringRequestEntity("{\"amount\":33}"));
|
||||
client.executeMethod(method);
|
||||
String response = method.getResponseBodyAsString();
|
||||
assertEquals(400, method.getStatusCode());
|
||||
|
||||
assertEquals("{\"actionErrors\":[],\"fieldErrors\":{\"clientName\":[\"The client name is empty\"]}}", response);
|
||||
assertNull(method.getResponseHeader("Location"));
|
||||
} finally {
|
||||
method.releaseConnection();
|
||||
}
|
||||
}
|
||||
}
|
||||
+53
-78
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-apps</artifactId>
|
||||
<version>6.0.3</version>
|
||||
<version>2.5.26</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-showcase</artifactId>
|
||||
@@ -89,19 +89,9 @@
|
||||
<artifactId>struts2-bean-validation-plugin</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-async-plugin</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-velocity-plugin</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -121,10 +111,16 @@
|
||||
<artifactId>log4j-jcl</artifactId>
|
||||
<version>${log4j2.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Velocity -->
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-slf4j-impl</artifactId>
|
||||
<version>${log4j2.version}</version>
|
||||
<groupId>org.apache.velocity</groupId>
|
||||
<artifactId>velocity</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.velocity</groupId>
|
||||
<artifactId>velocity-tools</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -132,7 +128,7 @@
|
||||
<artifactId>sitemesh</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.directwebremoting</groupId>
|
||||
<groupId>uk.ltd.getahead</groupId>
|
||||
<artifactId>dwr</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -140,24 +136,47 @@
|
||||
<artifactId>commons-fileupload</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.htmlunit</groupId>
|
||||
<artifactId>htmlunit</artifactId>
|
||||
<version>2.61.0</version>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.jwebunit</groupId>
|
||||
<artifactId>jwebunit-core</artifactId>
|
||||
<version>1.4.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-httpclient</groupId>
|
||||
<artifactId>commons-httpclient</artifactId>
|
||||
<version>3.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.jwebunit</groupId>
|
||||
<artifactId>jwebunit-htmlunit-plugin</artifactId>
|
||||
<version>1.4.1</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>xom</groupId>
|
||||
<artifactId>xom</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- BeanValidation Example -->
|
||||
<dependency>
|
||||
<groupId>org.hibernate.validator</groupId>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-validator</artifactId>
|
||||
<version>${hibernate-validator.version}</version>
|
||||
<version>5.4.3.Final</version>
|
||||
</dependency>
|
||||
|
||||
<!-- The Servlet API mocks in Spring Framework 4.x only supports Servlet 3.0 and higher.
|
||||
This is only necessary in tests-->
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
@@ -165,48 +184,22 @@
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<version>3.0.0-M6</version>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>it.org.apache.struts2.showcase.*Test</include>
|
||||
</includes>
|
||||
<systemPropertyVariables>
|
||||
<http.port>8090</http.port>
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>integration-test</id>
|
||||
<goals>
|
||||
<goal>integration-test</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>verify</id>
|
||||
<goals>
|
||||
<goal>verify</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<groupId>org.mortbay.jetty</groupId>
|
||||
<artifactId>jetty-maven-plugin</artifactId>
|
||||
<version>9.4.46.v20220331</version>
|
||||
<version>8.1.16.v20140903</version>
|
||||
<configuration>
|
||||
<stopKey>CTRL+C</stopKey>
|
||||
<stopPort>8999</stopPort>
|
||||
<systemProperties>
|
||||
<systemProperty>
|
||||
<name>log4j.configuration</name>
|
||||
<value>file:${basedir}/src/main/resources/log4j.properties</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>
|
||||
@@ -214,24 +207,6 @@
|
||||
<descriptor>${basedir}/src/main/webapp/WEB-INF/web.xml</descriptor>
|
||||
</webAppConfig>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>start-jetty</id>
|
||||
<phase>pre-integration-test</phase>
|
||||
<goals>
|
||||
<!-- stop any previous instance to free up the port -->
|
||||
<goal>stop</goal>
|
||||
<goal>start</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>stop-jetty</id>
|
||||
<phase>post-integration-test</phase>
|
||||
<goals>
|
||||
<goal>stop</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
|
||||
@@ -36,7 +36,6 @@ public class MoreSelectsAction extends ActionSupport {
|
||||
private List _prioritisedFavouriteCars;
|
||||
private List _prioritisedFavouriteCountries;
|
||||
private List favouriteNumbers;
|
||||
private List favouriteCities;
|
||||
|
||||
|
||||
// Cartoon Characters
|
||||
@@ -125,14 +124,6 @@ public class MoreSelectsAction extends ActionSupport {
|
||||
return list;
|
||||
}
|
||||
|
||||
public List getFavouriteCities() {
|
||||
return favouriteCities;
|
||||
}
|
||||
|
||||
public void setFavouriteCities(List favouriteCities) {
|
||||
this.favouriteCities = favouriteCities;
|
||||
}
|
||||
|
||||
// actions
|
||||
|
||||
public String input() throws Exception {
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
package org.apache.struts2.showcase.async;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.FilterConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Filters async actions directly to Struts servlet
|
||||
*/
|
||||
public class AsyncFilter implements Filter {
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
|
||||
String requestURI = ((HttpServletRequest) servletRequest).getRequestURI();
|
||||
if (!requestURI.contains("/async/receiveNewMessages")) {
|
||||
filterChain.doFilter(servletRequest, servletResponse); // Just continue chain.
|
||||
} else {
|
||||
servletRequest.getRequestDispatcher("/async/receiveNewMessages").forward(servletRequest, servletResponse);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,68 +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.
|
||||
*/
|
||||
package org.apache.struts2.showcase.async;
|
||||
|
||||
import com.opensymphony.xwork2.ActionSupport;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
/**
|
||||
* Example to illustrate the <code>async</code> plugin.
|
||||
*/
|
||||
public class ChatRoomAction extends ActionSupport {
|
||||
private String message;
|
||||
private Integer lastIndex;
|
||||
private List<String> newMessages;
|
||||
|
||||
private static final List<String> messages = new ArrayList<>();
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public void setLastIndex(Integer lastIndex) {
|
||||
this.lastIndex = lastIndex;
|
||||
}
|
||||
|
||||
public List<String> getNewMessages() {
|
||||
return newMessages;
|
||||
}
|
||||
|
||||
public Callable<String> receiveNewMessages() throws Exception {
|
||||
return new Callable<String>() {
|
||||
@Override
|
||||
public String call() throws Exception {
|
||||
while (lastIndex >= messages.size()) {
|
||||
Thread.sleep(3000);
|
||||
}
|
||||
newMessages = messages.subList(lastIndex, messages.size());
|
||||
return SUCCESS;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public String sendMessage() {
|
||||
synchronized (messages) {
|
||||
messages.add(message);
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
+14
-15
@@ -25,28 +25,27 @@ import com.opensymphony.xwork2.Action;
|
||||
import com.opensymphony.xwork2.ActionContext;
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.Map;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.struts2.dispatcher.SessionMap;
|
||||
|
||||
public class ChatAuthenticationInterceptor extends AbstractInterceptor {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Logger LOG = LogManager.getLogger(ChatAuthenticationInterceptor.class);
|
||||
public static final String USER_SESSION_KEY = "chatUserSessionKey";
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Logger LOG = LogManager.getLogger(ChatAuthenticationInterceptor.class);
|
||||
public static final String USER_SESSION_KEY = "chatUserSessionKey";
|
||||
|
||||
public String intercept(ActionInvocation invocation) throws Exception {
|
||||
public String intercept(ActionInvocation invocation) throws Exception {
|
||||
|
||||
LOG.debug("Authenticating chat user");
|
||||
LOG.debug("Authenticating chat user");
|
||||
|
||||
Map<String, Object> session = ActionContext.getContext().getSession();
|
||||
User user = (User) session.get(USER_SESSION_KEY);
|
||||
SessionMap session = (SessionMap) ActionContext.getContext().get(ActionContext.SESSION);
|
||||
User user = (User) session.get(USER_SESSION_KEY);
|
||||
|
||||
if (user == null) {
|
||||
return Action.LOGIN;
|
||||
}
|
||||
return invocation.invoke();
|
||||
}
|
||||
if (user == null) {
|
||||
return Action.LOGIN;
|
||||
}
|
||||
return invocation.invoke();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,31 +24,31 @@ import com.opensymphony.xwork2.Action;
|
||||
import com.opensymphony.xwork2.ActionContext;
|
||||
import com.opensymphony.xwork2.ActionInvocation;
|
||||
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
|
||||
import java.util.Map;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
/**
|
||||
* Authenticate showcase chat example, make sure everyone have a username.
|
||||
*/
|
||||
public class ChatInterceptor extends AbstractInterceptor {
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(ChatInterceptor.class);
|
||||
private static final Logger LOG = LogManager.getLogger(ChatInterceptor.class);
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static final String CHAT_USER_SESSION_KEY = "ChatUserSessionKey";
|
||||
public static final String CHAT_USER_SESSION_KEY = "ChatUserSessionKey";
|
||||
|
||||
public String intercept(ActionInvocation invocation) throws Exception {
|
||||
Map<String, Object> session = ActionContext.getContext().getSession();
|
||||
User chatUser = (User) session.get(CHAT_USER_SESSION_KEY);
|
||||
if (chatUser == null) {
|
||||
LOG.debug("Chat user not logged in");
|
||||
return Action.LOGIN;
|
||||
}
|
||||
return invocation.invoke();
|
||||
}
|
||||
public String intercept(ActionInvocation invocation) throws Exception {
|
||||
HttpSession session = (HttpSession) ActionContext.getContext().get(ActionContext.SESSION);
|
||||
User chatUser = (User) session.getAttribute(CHAT_USER_SESSION_KEY);
|
||||
if (chatUser == null) {
|
||||
LOG.debug("Chat user not logged in");
|
||||
return Action.LOGIN;
|
||||
}
|
||||
return invocation.invoke();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -20,8 +20,6 @@
|
||||
*/
|
||||
package org.apache.struts2.showcase.chat;
|
||||
|
||||
import com.opensymphony.xwork2.conversion.impl.XWorkConverter;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.struts2.util.StrutsTypeConverter;
|
||||
@@ -35,13 +33,6 @@ public class DateConverter extends StrutsTypeConverter {
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(DateConverter.class);
|
||||
|
||||
private XWorkConverter fallbackConverter;
|
||||
|
||||
@Inject
|
||||
public void setXWorkConverter(XWorkConverter fallbackConverter) {
|
||||
this.fallbackConverter = fallbackConverter;
|
||||
}
|
||||
|
||||
public Object convertFromString(Map context, String[] values, Class toClass) {
|
||||
|
||||
if (values.length > 0 && values[0] != null && values[0].trim().length() > 0) {
|
||||
@@ -49,8 +40,7 @@ public class DateConverter extends StrutsTypeConverter {
|
||||
try {
|
||||
return sdf.parse(values[0]);
|
||||
} catch (ParseException e) {
|
||||
LOG.warn("error converting value [" + values[0] + "] to Date. Trying fallback converter.");
|
||||
return this.fallbackConverter.convertValue(context, values[0], toClass);
|
||||
LOG.error("error converting value [" + values[0] + "] to Date ", e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
+3
-3
@@ -32,9 +32,9 @@ import java.io.File;
|
||||
*/
|
||||
public class MultipleFileUploadUsingArrayAction extends ActionSupport {
|
||||
|
||||
private File[] uploads = new File[0];
|
||||
private String[] uploadFileNames = new String[0];
|
||||
private String[] uploadContentTypes = new String[0];
|
||||
private File[] uploads;
|
||||
private String[] uploadFileNames;
|
||||
private String[] uploadContentTypes;
|
||||
|
||||
|
||||
public String upload() throws Exception {
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
package org.apache.struts2.showcase.model;
|
||||
|
||||
import org.apache.commons.text.StringEscapeUtils;
|
||||
import org.apache.commons.lang3.StringEscapeUtils;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
+164
-159
@@ -22,13 +22,15 @@ package org.apache.struts2.showcase.source;
|
||||
|
||||
import com.opensymphony.xwork2.ActionSupport;
|
||||
import com.opensymphony.xwork2.util.ClassLoaderUtil;
|
||||
import org.apache.struts2.action.ServletContextAware;
|
||||
import org.apache.struts2.ServletActionContext;
|
||||
import org.apache.struts2.util.ServletContextAware;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import java.io.BufferedReader;
|
||||
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;
|
||||
@@ -39,192 +41,195 @@ 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<String> pageLines;
|
||||
private List<String> classLines;
|
||||
private List<String> configLines;
|
||||
private List pageLines;
|
||||
private List classLines;
|
||||
private List 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 IOException {
|
||||
public String execute() throws MalformedURLException, 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/java" + 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" + className);
|
||||
}
|
||||
classLines = read(in, -1);
|
||||
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
String rootPath = ServletActionContext.getServletContext().getRealPath("/");
|
||||
|
||||
if (config != null && (rootPath == null || config.startsWith(rootPath))) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @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<String> getClassLines() {
|
||||
return classLines;
|
||||
}
|
||||
/**
|
||||
* @return the classLines
|
||||
*/
|
||||
public List getClassLines() {
|
||||
return classLines;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the configLines
|
||||
*/
|
||||
public List<String> getConfigLines() {
|
||||
return configLines;
|
||||
}
|
||||
/**
|
||||
* @return the configLines
|
||||
*/
|
||||
public List getConfigLines() {
|
||||
return configLines;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the pageLines
|
||||
*/
|
||||
public List<String> getPageLines() {
|
||||
return pageLines;
|
||||
}
|
||||
/**
|
||||
* @return the pageLines
|
||||
*/
|
||||
public List 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<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));
|
||||
/**
|
||||
* Reads in a strea, 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));
|
||||
|
||||
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 setServletContext(ServletContext arg0) {
|
||||
this.servletContext = arg0;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+16
-14
@@ -27,24 +27,22 @@ import org.apache.struts2.convention.annotation.Namespace;
|
||||
import org.apache.struts2.convention.annotation.ParentPackage;
|
||||
import org.apache.struts2.convention.annotation.Result;
|
||||
import org.apache.struts2.interceptor.validation.SkipValidation;
|
||||
import org.hibernate.validator.constraints.Email;
|
||||
import org.hibernate.validator.constraints.NotBlank;
|
||||
import org.hibernate.validator.constraints.ScriptAssert;
|
||||
import org.hibernate.validator.constraints.URL;
|
||||
|
||||
import javax.validation.constraints.Email;
|
||||
import javax.validation.constraints.Max;
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Pattern;
|
||||
import javax.validation.constraints.Size;
|
||||
import javax.validation.constraints.*;
|
||||
import java.util.Date;
|
||||
|
||||
// <!-- START SNIPPET: beanValidationExample -->
|
||||
/**
|
||||
* <!-- START SNIPPET: beanValidatationExample -->
|
||||
*/
|
||||
@Namespace("/bean-validation")
|
||||
@ParentPackage("bean-validation")
|
||||
@Action(results = {
|
||||
@Result(name = "input", location = "bean-validation.jsp"),
|
||||
@Result(name = "success", location = "/WEB-INF/validation/successFieldValidatorsExample.jsp")
|
||||
@Result(name = "input", location = "bean-validation.jsp"),
|
||||
@Result(name = "success", location = "/WEB-INF/validation/successFieldValidatorsExample.jsp")
|
||||
})
|
||||
@FieldMatch(first = "fieldExpressionValidatorField", second = "requiredValidatorField", message = "requiredValidatorField and fieldExpressionValidatorField are not matching")
|
||||
@ScriptAssert(lang = "javascript", script = "_this.dateValidatorField != null && _this.dateValidatorField.before(new java.util.Date())", message = "Date need to before now")
|
||||
@@ -84,10 +82,10 @@ public class BeanValidationExampleAction extends ActionSupport {
|
||||
private String fieldExpressionValidatorField = null;
|
||||
|
||||
@Action(value = "bean-validation", results = {
|
||||
@Result(name = "success", location = "bean-validation.jsp")
|
||||
@Result(name = "success", location = "bean-validation.jsp")
|
||||
})
|
||||
@SkipValidation
|
||||
public String beanValidation() {
|
||||
public String beanValidation(){
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@@ -152,7 +150,7 @@ public class BeanValidationExampleAction extends ActionSupport {
|
||||
}
|
||||
|
||||
public void setFieldExpressionValidatorField(
|
||||
String fieldExpressionValidatorField) {
|
||||
String fieldExpressionValidatorField) {
|
||||
this.fieldExpressionValidatorField = fieldExpressionValidatorField;
|
||||
}
|
||||
|
||||
@@ -165,4 +163,8 @@ public class BeanValidationExampleAction extends ActionSupport {
|
||||
}
|
||||
}
|
||||
|
||||
// <!-- END SNIPPET: beanValidationExample -->
|
||||
/**
|
||||
* <!-- END SNIPPET: beanValidatationExample -->
|
||||
*/
|
||||
|
||||
|
||||
|
||||
@@ -22,14 +22,15 @@
|
||||
<Configuration>
|
||||
<Appenders>
|
||||
<Console name="STDOUT" target="SYSTEM_OUT">
|
||||
<PatternLayout pattern="[%-5p] %C{2} (%F:%L) - %m%n"/>
|
||||
<PatternLayout pattern="%d %-5p [%t] %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>
|
||||
+1
-1
@@ -71,7 +71,7 @@
|
||||
</field>
|
||||
<field name="regexValidatorField">
|
||||
<field-validator type="regex">
|
||||
<param name="regex"><![CDATA[ .*\.txt ]]></param>
|
||||
<param name="regex"><![CDATA[ [^<>]+ ]]></param>
|
||||
<message><![CDATA[ regexValidatorField must match a regexp (.*\.txt) if specified ]]></message>
|
||||
</field-validator>
|
||||
</field>
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
<?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"
|
||||
"http://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
|
||||
<struts>
|
||||
<package name="async" extends="json-default" namespace="/async">
|
||||
|
||||
<action name="receiveNewMessages" class="org.apache.struts2.showcase.async.ChatRoomAction" method="receiveNewMessages">
|
||||
<result name="success" type="json">
|
||||
<param name="root">newMessages</param>
|
||||
</result>
|
||||
<result name="timeout" type="json">
|
||||
<param name="root">newMessages</param>
|
||||
</result>
|
||||
</action>
|
||||
|
||||
<action name="sendMessage" class="org.apache.struts2.showcase.async.ChatRoomAction" method="sendMessage">
|
||||
<result name="success" type="json">
|
||||
<param name="root">newMessages</param>
|
||||
</result>
|
||||
<result name="timeout" type="json">
|
||||
<param name="root">newMessages</param>
|
||||
</result>
|
||||
</action>
|
||||
|
||||
</package>
|
||||
|
||||
</struts>
|
||||
@@ -1,40 +0,0 @@
|
||||
<?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"
|
||||
"http://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>
|
||||
@@ -24,7 +24,7 @@
|
||||
"http://struts.apache.org/dtds/struts-2.5.dtd">
|
||||
|
||||
<struts>
|
||||
<package name="ui-tags" extends="velocity-default" namespace="/tags/ui">
|
||||
<package name="ui-tags" extends="struts-default" namespace="/tags/ui">
|
||||
<action name="example" class="org.apache.struts2.showcase.UITagExample">
|
||||
<result>/WEB-INF/tags/ui/example.jsp</result>
|
||||
<result name="input">/WEB-INF/tags/ui/example.jsp</result>
|
||||
|
||||
@@ -47,11 +47,6 @@
|
||||
<result>/WEB-INF/validation/quiz-success.jsp</result>
|
||||
</action>
|
||||
|
||||
<action name="quizDwr" class="org.apache.struts2.showcase.validation.QuizAction">
|
||||
<result name="input">/WEB-INF/validation/quiz-dwr.jsp</result>
|
||||
<result>/WEB-INF/validation/quiz-success.jsp</result>
|
||||
</action>
|
||||
|
||||
<action name="quizClientCss" class="org.apache.struts2.showcase.validation.QuizAction">
|
||||
<result name="input">/WEB-INF/validation/quiz-client-css.jsp</result>
|
||||
<result>/WEB-INF/validation/quiz-success.jsp</result>
|
||||
|
||||
@@ -44,8 +44,6 @@
|
||||
<constant name="struts.serve.static" value="true" />
|
||||
<constant name="struts.serve.static.browserCache" value="false" />
|
||||
|
||||
<constant name="struts.action.excludePattern" value=".*/images/.*\.gif,.*/img/.*\.gif,.*/styles/.*\.css,.*/js/.*\.js"/>
|
||||
|
||||
<include file="struts-interactive.xml" />
|
||||
|
||||
<include file="struts-hangman.xml" />
|
||||
@@ -76,10 +74,6 @@
|
||||
|
||||
<include file="struts-xslt.xml" />
|
||||
|
||||
<include file="struts-async.xml" />
|
||||
|
||||
<include file="struts-dispatcher.xml" />
|
||||
|
||||
<package name="default" extends="struts-default">
|
||||
<interceptors>
|
||||
<interceptor-stack name="crudStack">
|
||||
|
||||
@@ -23,21 +23,21 @@
|
||||
-->
|
||||
<ul<#rt/>
|
||||
<#if parameters.id??>
|
||||
id="${parameters.id}"<#rt/>
|
||||
id="${parameters.id?html}"<#rt/>
|
||||
</#if>
|
||||
<#if parameters.cssClass??>
|
||||
class="${parameters.cssClass}"<#rt/>
|
||||
class="${parameters.cssClass?html}"<#rt/>
|
||||
<#else>
|
||||
class="errorMessage"<#rt/>
|
||||
</#if>
|
||||
<#if parameters.cssStyle??>
|
||||
style="${parameters.cssStyle}"<#rt/>
|
||||
style="${parameters.cssStyle?html}"<#rt/>
|
||||
</#if>
|
||||
>
|
||||
<#if (actionErrors?? && actionErrors?size > 0)>
|
||||
<#list actionErrors as error>
|
||||
<#if error??>
|
||||
<li><span><#if parameters.escape>${error!}<#else>${error!}</#if></span><#rt/></li><#rt/>
|
||||
<li><span><#if parameters.escape>${error!?html}<#else>${error!}</#if></span><#rt/></li><#rt/>
|
||||
</#if>
|
||||
</#list>
|
||||
</#if>
|
||||
|
||||
@@ -22,13 +22,13 @@ ${parameters.after!}<#t/>
|
||||
</td><#lt/>
|
||||
</tr>
|
||||
<#if (parameters.errorposition!"top") == 'bottom'>
|
||||
<#assign hasFieldErrors = parameters.name?? && fieldErrors?? && fieldErrors.get(parameters.name)??/>
|
||||
<#assign hasFieldErrors = parameters.name?? && fieldErrors?? && fieldErrors[parameters.name]??/>
|
||||
<#if hasFieldErrors>
|
||||
<tr errorFor="${parameters.id}">
|
||||
<td class="tdErrorMessage" colspan="2"><#rt/>
|
||||
<#if hasFieldErrors>
|
||||
<#list fieldErrors.get(parameters.name) as error>
|
||||
<div class="errorMessage">${error}</div><#t/>
|
||||
<#list fieldErrors[parameters.name] as error>
|
||||
<div class="errorMessage">${error?html}</div><#t/>
|
||||
</#list>
|
||||
</#if>
|
||||
</td><#lt/>
|
||||
|
||||
+12
-12
@@ -21,29 +21,29 @@
|
||||
<#--
|
||||
Always include elements to show errors. They may be filled later via AJAX.
|
||||
-->
|
||||
<#assign hasFieldErrors = parameters.name?? && fieldErrors?? && fieldErrors.get(parameters.name)??/>
|
||||
<#assign hasFieldErrors = parameters.name?? && fieldErrors?? && fieldErrors[parameters.name]??/>
|
||||
<#if (parameters.errorposition!"top") == 'top'>
|
||||
<tr errorFor="${parameters.id}">
|
||||
<td class="tdErrorMessage" colspan="2" data-error-for-fieldname="${parameters.name}"><#rt/>
|
||||
<#if hasFieldErrors>
|
||||
<#list fieldErrors.get(parameters.name) as error>
|
||||
<div class="errorMessage">${error}</div><#t/>
|
||||
<#list fieldErrors[parameters.name] as error>
|
||||
<div class="errorMessage">${error?html}</div><#t/>
|
||||
</#list>
|
||||
</#if>
|
||||
</td><#lt/>
|
||||
</tr>
|
||||
</#if>
|
||||
<#if !parameters.labelPosition?? && (parameters.form.labelPosition)??>
|
||||
<#assign labelPos = parameters.form.labelPosition/>
|
||||
<#elseif parameters.labelPosition??>
|
||||
<#assign labelpos = parameters.labelPosition/>
|
||||
<#if !parameters.labelposition?? && (parameters.form.labelposition)??>
|
||||
<#assign labelpos = parameters.form.labelposition/>
|
||||
<#elseif parameters.labelposition??>
|
||||
<#assign labelpos = parameters.labelposition/>
|
||||
</#if>
|
||||
<#--
|
||||
if the label position is top,
|
||||
then give the label it's own row in the table
|
||||
-->
|
||||
<tr>
|
||||
<#if (labelPos!"") == 'top'>
|
||||
<#if (labelpos!"") == 'top'>
|
||||
<td class="tdLabelTop" colspan="2"><#rt/>
|
||||
<#else>
|
||||
<td class="tdLabel"><#rt/>
|
||||
@@ -51,7 +51,7 @@
|
||||
<#if parameters.label??>
|
||||
<label <#t/>
|
||||
<#if parameters.id??>
|
||||
for="${parameters.id}" <#t/>
|
||||
for="${parameters.id?html}" <#t/>
|
||||
</#if>
|
||||
<#if hasFieldErrors>
|
||||
class="errorLabel"<#t/>
|
||||
@@ -62,17 +62,17 @@
|
||||
<#if parameters.required!false && parameters.requiredPosition!"right" != 'right'>
|
||||
<span class="required">*</span><#t/>
|
||||
</#if>
|
||||
${parameters.label}<#t/>
|
||||
${parameters.label?html}<#t/>
|
||||
<#if parameters.required!false && parameters.requiredPosition!"right" == 'right'>
|
||||
<span class="required">*</span><#t/>
|
||||
</#if>
|
||||
${parameters.labelseparator!":"}<#t/>
|
||||
${parameters.labelseparator!":"?html}<#t/>
|
||||
<#include "/${parameters.templateDir}/${parameters.expandTheme}/tooltip.ftl" />
|
||||
</label><#t/>
|
||||
</#if>
|
||||
</td><#lt/>
|
||||
<#-- add the extra row -->
|
||||
<#if (labelPos!"") == 'top'>
|
||||
<#if (labelpos!"") == 'top'>
|
||||
</tr>
|
||||
<tr>
|
||||
</#if>
|
||||
|
||||
@@ -45,46 +45,66 @@
|
||||
</bean>
|
||||
|
||||
<bean id="chatLoginAction" class="org.apache.struts2.showcase.chat.ChatLoginAction" scope="prototype">
|
||||
<constructor-arg index="0" ref="chatService"/>
|
||||
<constructor-arg index="0">
|
||||
<ref local="chatService"/>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean id="chatLogoutAction" class="org.apache.struts2.showcase.chat.ChatLogoutAction" scope="prototype">
|
||||
<constructor-arg index="0" ref="chatService"/>
|
||||
<constructor-arg index="0">
|
||||
<ref local="chatService"/>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean id="usersAvailableAction" class="org.apache.struts2.showcase.chat.UsersAvailableAction" scope="prototype">
|
||||
<constructor-arg index="0" ref="chatService"/>
|
||||
<constructor-arg index="0">
|
||||
<ref local="chatService"/>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean id="roomsAvailableAction" class="org.apache.struts2.showcase.chat.RoomsAvailableAction" scope="prototype">
|
||||
<constructor-arg index="0" ref="chatService"/>
|
||||
<constructor-arg index="0">
|
||||
<ref local="chatService"/>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean id="crudRoomAction" class="org.apache.struts2.showcase.chat.CrudRoomAction" scope="prototype">
|
||||
<constructor-arg index="0" ref="chatService"/>
|
||||
<constructor-arg index="0">
|
||||
<ref local="chatService"/>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean id="enterRoomAction" class="org.apache.struts2.showcase.chat.EnterRoomAction" scope="prototype">
|
||||
<constructor-arg index="0" ref="chatService"/>
|
||||
<constructor-arg index="0">
|
||||
<ref local="chatService"/>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean id="messagesAvailableInRoomAction" class="org.apache.struts2.showcase.chat.MessagesAvailableInRoomAction"
|
||||
scope="prototype">
|
||||
<constructor-arg index="0" ref="chatService"/>
|
||||
<constructor-arg index="0">
|
||||
<ref local="chatService"/>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean id="sendMessageToRoomAction" class="org.apache.struts2.showcase.chat.SendMessageToRoomAction"
|
||||
scope="prototype">
|
||||
<constructor-arg index="0" ref="chatService"/>
|
||||
<constructor-arg index="0">
|
||||
<ref local="chatService"/>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean id="usersAvailableInRoomAction" class="org.apache.struts2.showcase.chat.UsersAvailableInRoomAction"
|
||||
scope="prototype">
|
||||
<constructor-arg index="0" ref="chatService"/>
|
||||
<constructor-arg index="0">
|
||||
<ref local="chatService"/>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean id="exitRoomAction" class="org.apache.struts2.showcase.chat.ExitRoomAction" scope="prototype">
|
||||
<constructor-arg index="0" ref="chatService"/>
|
||||
<constructor-arg index="0">
|
||||
<ref local="chatService"/>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
|
||||
@@ -109,7 +129,9 @@
|
||||
</bean>
|
||||
|
||||
<bean id="startHangmanAction" class="org.apache.struts2.showcase.hangman.StartHangmanAction" scope="prototype">
|
||||
<constructor-arg index="0" ref="hangmanService"/>
|
||||
<constructor-arg index="0">
|
||||
<ref local="hangmanService"/>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean id="guessCharacterAction" class="org.apache.struts2.showcase.hangman.GuessCharacterAction" scope="prototype"/>
|
||||
|
||||
@@ -63,32 +63,26 @@
|
||||
|
||||
<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:url var="mainCss" value='/styles/main.css' encode='false' includeParams='none'/>
|
||||
<s:link href="%{mainCss}" rel="stylesheet" type="text/css" media="all"></s:link>
|
||||
<link href="<s:url value='/styles/bootstrap.css' encode='false' includeParams='none'/>" rel="stylesheet" type="text/css" media="all">
|
||||
<link href="<s:url value='/styles/main.css' encode='false' includeParams='none'/>" 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:url var="bootstrapJs" value='/js/bootstrap.min.js' encode='false' includeParams='none'/>
|
||||
<s:script src="%{bootstrapJs}"></s:script>
|
||||
<s:script type="text/javascript">
|
||||
<script src="<s:url value='/js/jquery-2.1.4.min.js' encode='false' includeParams='none'/>"></script>
|
||||
<script src="<s:url value='/js/bootstrap.min.js' encode='false' includeParams='none'/>"></script>
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
var alerts = $('ul.alert').wrap('<div />');
|
||||
alerts.prepend('<a class="close" data-dismiss="alert" href="#">×</a>');
|
||||
alerts.alert();
|
||||
});
|
||||
</s:script>
|
||||
</script>
|
||||
|
||||
<!-- Prettify -->
|
||||
<s:url var="prettifyCss" value='/styles/prettify.css' encode='false' includeParams='none'/>
|
||||
<s:link href="%{prettifyCss}" rel="stylesheet"></s:link>
|
||||
<s:url var="prettifyJs" value='/js/prettify.js' encode='false' includeParams='none'/>
|
||||
<s:script src="%{prettifyJs}"></s:script>
|
||||
<link href="<s:url value='/styles/prettify.css' encode='false' includeParams='none'/>" rel="stylesheet">
|
||||
<script src="<s:url value='/js/prettify.js' encode='false' includeParams='none'/>"></script>
|
||||
|
||||
<!-- 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>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
<decorator:head/>
|
||||
@@ -207,7 +201,6 @@
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<s:url var="quizBasic" namespace="/validation" action="quizBasic" method="input"/>
|
||||
<s:url var="quizClient" namespace="/validation" action="quizClient" method="input"/>
|
||||
<s:url var="quizDwr" namespace="/validation" action="quizDwr" method="input"/>
|
||||
<s:url var="quizClientCss" namespace="/validation" action="quizClientCss" method="input"/>
|
||||
<s:url var="fieldValidatorUrl" action="showFieldValidatorsExamples" namespace="/validation"/>
|
||||
<s:url var="nonFieldValidatorUrl" action="showNonFieldValidatorsExamples" namespace="/validation"/>
|
||||
@@ -223,7 +216,6 @@
|
||||
<li><s:a href="%{storeMessageAcrossRequestExample}">Store across request using MessageStoreInterceptor (Example)</s:a></li>
|
||||
<li><s:a href="%{quizBasic}">Validation (basic)</s:a></li>
|
||||
<li><s:a href="%{quizClient}">Validation (client)</s:a></li>
|
||||
<li><s:a href="%{quizDwr}">Validation (DWR)</s:a></li>
|
||||
<li><s:a href="%{quizClientCss}">Validation (client using css_xhtml theme)</s:a></li>
|
||||
<li><s:a href="%{visitorValidatorUrl}">Visitor Validator</s:a></li>
|
||||
<li><s:a href="%{ajaxFormSubmitUrl}">AJAX Form Submit</s:a></li>
|
||||
@@ -243,9 +235,6 @@
|
||||
<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">
|
||||
|
||||
@@ -1,42 +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.
|
||||
*/
|
||||
-->
|
||||
<%@ 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>
|
||||
@@ -39,7 +39,7 @@
|
||||
</div>
|
||||
|
||||
<s:url var="url" action="download"/>
|
||||
<s:a href="%{url}" cssClass="btn btn-large btn-info"><i class="icon-picture"></i> Download image file.</s:a>
|
||||
<s:a href="%{url}" cssClass="btn btn-large btn-info"><i class="icon-picture"></i> Download image file.</s:a>
|
||||
</div>
|
||||
<div class="col-md-6" style="text-align: center;">
|
||||
<div class="alert alert-info">
|
||||
@@ -47,7 +47,7 @@
|
||||
</div>
|
||||
|
||||
<s:url var="url" action="download2"/>
|
||||
<s:a href="%{url}" cssClass="btn btn-large btn-info"><i class="icon-download-alt"></i> Download ZIP file.</s:a>
|
||||
<s:a href="%{url}" cssClass="btn btn-large btn-info"><i class="icon-download-alt"></i> Download ZIP file.</s:a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -139,7 +139,6 @@
|
||||
|
||||
<@s.a href="%{#url}"
|
||||
id="%{#currentCharacter}"
|
||||
|
||||
>
|
||||
<img height="36" alt="" src="<@s.property value="%{#chalkboardImageUrl}" />" width="36" border="0" />
|
||||
</@s.a>
|
||||
|
||||
@@ -51,9 +51,9 @@
|
||||
</tr>
|
||||
<#list people as person>
|
||||
<tr>
|
||||
<td>${person.id}</td>
|
||||
<td>${person.name}</td>
|
||||
<td>${person.lastName}</td>
|
||||
<td>${person.id?html}</td>
|
||||
<td>${person.name?html}</td>
|
||||
<td>${person.lastName?html}</td>
|
||||
</tr>
|
||||
</#list>
|
||||
</table>
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
<p>You have come to this page because you used an <strong>action</strong> prefix.<p/>
|
||||
|
||||
<p>The text you've entered is ${text!''}<p/>
|
||||
<p>The text you've entered is ${text!''?html}<p/>
|
||||
|
||||
<@s.a href="javascript:history.back();" cssClass="btn btn-info"><i class="icon icon-arrow-left"></i> Back</@s.a>
|
||||
</div>
|
||||
|
||||
@@ -32,8 +32,8 @@
|
||||
<div class="col-md-12">
|
||||
|
||||
<p>You have come to this page because you used an <strong>method</strong> prefix.<p/>
|
||||
|
||||
<p>The text you've enter is ${text!''}<p/>
|
||||
|
||||
<p>The text you've enter is ${text!''?html}<p/>
|
||||
|
||||
<@s.a href="javascript:history.back();" cssClass="btn btn-info"><i class="icon icon-arrow-left"></i> Back</@s.a>
|
||||
</div>
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
<div class="col-md-12">
|
||||
|
||||
<p>You have come to this page because you did a normal submit.<p/>
|
||||
|
||||
|
||||
<p>The text you've enter is %{text}<p/>
|
||||
|
||||
<@s.a href="javascript:history.back();" cssClass="btn btn-info"><i class="icon icon-arrow-left"></i> Back</@s.a>
|
||||
|
||||
+2
-2
@@ -32,11 +32,11 @@
|
||||
<div class="col-md-12">
|
||||
|
||||
<p>You have come to this page because you used an 'redirect-action' prefix.<p/>
|
||||
|
||||
|
||||
<p>Because this is a <strong>redirect-action</strong>, the text will be lost, due to a redirection
|
||||
implies a new request being issued from the client.<p/>
|
||||
|
||||
The text you've enter is ${text!''}<p/>
|
||||
The text you've enter is ${text!''?html}<p/>
|
||||
|
||||
<@s.a href="javascript:history.back();" cssClass="btn btn-info"><i class="icon icon-arrow-left"></i> Back</@s.a>
|
||||
</div>
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
<s:fielderror cssClass="alert alert-error"/>
|
||||
|
||||
|
||||
<s:form action="exampleSubmit" enctype="multipart/form-data" method="POST" javascriptTooltip="true">
|
||||
<s:form action="exampleSubmit" enctype="multipart/form-data" javascriptTooltip="true">
|
||||
<s:textfield
|
||||
label="Name"
|
||||
name="name"
|
||||
@@ -97,7 +97,7 @@
|
||||
cssErrorClass="foo" />
|
||||
|
||||
<s:checkbox
|
||||
tooltip="Confirm that you are Over 18"
|
||||
tooltip="Confirmed that your are Over 18"
|
||||
label="Age 18+"
|
||||
name="legalAge"/>
|
||||
|
||||
@@ -114,8 +114,8 @@
|
||||
emptyOption="true" />
|
||||
|
||||
<s:doubleselect
|
||||
tooltip="Choose your Vehicle"
|
||||
label="Favourite Vehicle"
|
||||
tooltip="Choose your Vehical"
|
||||
label="Favourite Vehical"
|
||||
name="favouriteVehicalType"
|
||||
list="vehicalTypeList"
|
||||
listKey="key"
|
||||
@@ -136,7 +136,7 @@
|
||||
|
||||
<s:optiontransferselect
|
||||
tooltip="Select Your Favourite Cartoon Characters"
|
||||
label="Favourite Cartoon Characters"
|
||||
label="Favourite Cartoons Characters"
|
||||
name="leftSideCartoonCharacters"
|
||||
leftTitle="Left Title"
|
||||
rightTitle="Right Title"
|
||||
@@ -153,7 +153,7 @@
|
||||
doubleMultiple="true" />
|
||||
|
||||
<s:textarea
|
||||
label="Your Thoughts"
|
||||
label="Your Thougths"
|
||||
name="thoughts"
|
||||
tooltip="Enter your thoughts here" />
|
||||
|
||||
|
||||
@@ -31,20 +31,16 @@
|
||||
<div class="col-md-12">
|
||||
|
||||
#sform ("action=exampleSubmitVelocity" "method=post" "enctype=multipart/form-data")
|
||||
#stextfield ("label=Name" "name=name" "tooltip=Enter your Name here")
|
||||
#stextfield ("label=Birthday" "name=birthday" "tooltip=Select Your Birthday")
|
||||
#stextfield ("label=Wake up time" "name=wakeup" "tooltip=Enter the time you wake up")
|
||||
#stextarea ("label=Biography" "name=bio" "tooltip=Enter your Biography" "cols=20" "rows=3")
|
||||
#sselect ("label=Favourite Color" "tooltip=Choose Your Favourite Color" "list={'Red', 'Blue', 'Green'}" "name=favouriteColor" "emptyOption=true" "headerKey=None" "headerValue=None")
|
||||
#sselect ("label=Favourite Language" "tooltip=Choose Your Favourite Language" "list=favouriteLanguages" "name=favouriteLanguage" "listKey=key" "listValue=description" "emptyOption=true" "headerKey=None" "headerValue=None")
|
||||
#scheckboxlist ("label=Friends" "tooltip=Choose your Friends" "list={'Wes', 'Patrick', 'Jason', 'Jay', 'Toby', 'Rene'}" "name=friends")
|
||||
#sradio ("label=Best Friend" "tooltip=Choose your Best Friend" "list={'Wes', 'Patrick', 'Jason', 'Jay', 'Toby', 'Rene'}" "name=bestFriend" "cssErrorClass=foo")
|
||||
#scheckbox ("label=Age 18+" "name=legalAge" "tooltip=Confirm that you are Over 18")
|
||||
#sdoubleselect ("label=State" "name=region" "tooltip=Choose Your State" "list={'North', 'South'}" "value='North'" "doubleValue='Florida'" "doubleList=top == 'North' ? {'Oregon', 'Washington'} : {'Texas', 'Florida'}" "doubleName=state" "headerKey=-1" "headerValue=---------- Please Select ----------" "emptyOption=true" )
|
||||
#sdoubleselect ("label=Favourite Vehicle" "name=favouriteVehicalType" "tooltip=Choose your Vehicle" "list=vehicalTypeList" "listKey=key" "listValue=description" "value='MotorcycleKey'" "doubleValue='YamahaKey'" "doubleList=vehicalSpecificList" "doubleListKey=key" "doubleListValue=description" "doubleName=favouriteVehicalSpecific" "headerKey=-1" "headerValue=---------- Please Select ----------" "emptyOption=true" )
|
||||
#sfile ("label=Picture" "name=picture" "tooltip=Upload Your Picture")
|
||||
#soptiontransferselect ("label=Favourite Cartoon Characters" "name=leftSideCartoonCharacters" "tooltip=Select Your Favourite Cartoon Characters" "leftTitle=Left Title" "rightTitle=Right Title" "list={'Popeye', 'He-Man', 'Spiderman'}" "multiple=true" "headerKey=headerKey" "headerValue=--- Please Select ---" "emptyOption=true" "doubleList={'Superman', 'Mickey Mouse', 'Donald Duck'}" "doubleName=rightSideCartoonCharacters" "doubleHeaderKey=doubleHeaderKey" "doubleHeaderValue=--- Please Select ---" "doubleEmptyOption=true" "doubleMultiple=true" )
|
||||
#stextarea ("label=Your Thoughts" "name=thoughts" "tooltip=Enter your thoughts here" "cols=20" "rows=3")
|
||||
#stextfield ("label=Name" "name=name")
|
||||
#stextarea ("label=Biography" "name=bio" "cols=20" "rows=3")
|
||||
#sselect ("label=Favourite Color" "list={'Red', 'Blue', 'Green'}" "name=favouriteColor" "emptyOption=true" "headerKey=None" "headerValue=None")
|
||||
#sselect ("label=Favourite Language" "list=favouriteLanguages" "name=favouriteLanguage" "listKey=key" "listValue=description" "emptyOption=true" "headerKey=None" "headerValue=None")
|
||||
#scheckboxlist ("label=Friends" "list={'Patrick', 'Jason', 'Jay', 'Toby', 'Rene'}" "name=friends")
|
||||
#scheckbox ("label=Age 18+" "name=legalAge")
|
||||
#sdoubleselect ("label=State" "name=region" "list={'North', 'South'}" "value='North'" "doubleValue='Florida'" "doubleList=top == 'North' ? {'Oregon', 'Washington'} : {'Texas', 'Florida'}" "doubleName=state" "headerKey=-1" "headerValue=---------- Please Select ----------" "emptyOption=true" )
|
||||
#sdoubleselect ("label=Favourite Vehical" "name=favouriteVehicalType" "list=vehicalTypeList" "listKey=key" "listValue=description" "value='MotorcycleKey'" "doubleValue='YamahaKey'" "doubleList=vehicalSpecificList" "doubleListKey=key" "doubleListValue=description" "doubleName=favouriteVehicalSpecific" "headerKey=-1" "headerValue=---------- Please Select ----------" "emptyOption=true" )
|
||||
#sfile ("label=Picture" "name=picture")
|
||||
#soptiontransferselect ("label=Favourite Cartoons Characters" "name=leftSideCartoonCharacters" "leftTitle=Left Title" "rightTitle=Right Title" "list={'Popeye', 'He-Man', 'Spiderman'}" "multiple=true" "headerKey=headerKey" "headerValue=--- Please Select ---" "emptyOption=true" "doubleList={'Superman', 'Mickey Mouse', 'Donald Duck'}" "doubleName=rightSideCartoonCharacters" "doubleHeaderKey=doubleHeaderKey" "doubleHeaderValue=--- Please Select ---" "doubleEmptyOption=true" "doubleMultiple=true" )
|
||||
#ssubmit("cssClass=btn btn-primary")
|
||||
#sreset("cssClass=btn btn-danger")
|
||||
#end
|
||||
|
||||
@@ -36,8 +36,8 @@
|
||||
<s:label label="Name" name="name" />
|
||||
<s:label label="Birthday" name="birthday" />
|
||||
<tr>
|
||||
<td class="tdLabel"><label class="label">Wake up time:</label></td>
|
||||
<td class="tdInput">
|
||||
<td><label class="label">Wake up time:</label></td>
|
||||
<td>
|
||||
<s:date name="wakeup" format="hh:mm aa" />
|
||||
</td>
|
||||
</tr>
|
||||
@@ -50,24 +50,22 @@
|
||||
<s:label label="State" name="state" />
|
||||
<s:label label="Picture" name="picture" />
|
||||
<s:label label="Favourite Language" name="favouriteLanguage" />
|
||||
<s:label label="Favourite Vehicle Type" name="favouriteVehicalType" />
|
||||
<s:label label="Favourite Vehicle Specific" name="favouriteVehicalSpecific" />
|
||||
<s:label label="Favourite Vehical Type" name="favouriteVehicalType" />
|
||||
<s:label label="Favourite Vehical Specific" name="favouriteVehicalSpecific" />
|
||||
<tr>
|
||||
<td class="tdLabel"><label class="label">Favourite Cartoon Characters (Left):</label></td>
|
||||
<td class="tdInput"><label>
|
||||
<td><label class="label">Favourite Cartoon Characters (Left):</label></td>
|
||||
<td>
|
||||
<s:iterator value="leftSideCartoonCharacters" status="stat">
|
||||
<s:property value="%{#stat.count}" />.<s:property value="top" />
|
||||
</s:iterator>
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tdLabel"><label class="label">Favourite Cartoon Characters (Right):</label></td>
|
||||
<td class="tdInput"><label>
|
||||
<td><label class="label">Favourite Cartoon Characters (Right):</label></td>
|
||||
<td>
|
||||
<s:iterator value="rightSideCartoonCharacters" status="stat">
|
||||
<s:property value="%{#stat.count}" />.<s:property value="top" />
|
||||
</s:iterator>
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<s:label label="Thoughts" name="thoughts" />
|
||||
|
||||
@@ -33,45 +33,41 @@
|
||||
#slabel ("label=Name" "name=name")
|
||||
#slabel ("label=Birthday" "name=birthday")
|
||||
<tr>
|
||||
<td class="tdLabel"><label class="label">Wake up time:</label></td>
|
||||
<td class="tdInput">
|
||||
<td><label class="label">Wake up time:</label></td>
|
||||
<td>
|
||||
#sdate ("name=wakeup" "format=hh:mm aa")
|
||||
</td>
|
||||
</tr>
|
||||
#slabel ("label=Biography" "name=bio")
|
||||
#slabel ("label=Favourite Color" "name=favouriteColor")
|
||||
#slabel ("label=Friends" "name=friends")
|
||||
#slabel ("label=Best Friend" "name=bestFriend")
|
||||
#slabel ("label=Legal Age" "name=legalAge")
|
||||
#slabel ("label=Region" "name=region")
|
||||
#slabel ("label=State" "name=state")
|
||||
#slabel ("label=Picture" "name=picture")
|
||||
#slabel ("label=Favourite Language" "name=favouriteLanguage")
|
||||
#slabel ("label=Favourite Vehicle Type" "name=favouriteVehicalType")
|
||||
#slabel ("label=Favourite Vehicle Specific" "name=favouriteVehicalSpecific")
|
||||
#slabel ("label=Favourite Vehical Type" "name=favouriteVehicalType")
|
||||
#slabel ("label=Favourite Vehical Specific" "name=favouriteVehicalSpecific")
|
||||
<tr>
|
||||
<td class="tdLabel"><label class="label">Favourite Cartoon Characters (Left):</label></td>
|
||||
<td class="tdInput"><label>
|
||||
<td>Favourite Cartoon Characters (Left):</td>
|
||||
<td>
|
||||
#set ( $startCount = 1)
|
||||
#foreach( $item in $leftSideCartoonCharacters)
|
||||
$startCount.${item}
|
||||
#set ( $startCount = $startCount + 1)
|
||||
#end
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tdLabel"><label class="label">Favourite Cartoon Characters (Right):</label></td>
|
||||
<td class="tdInput"><label>
|
||||
<td>Favourite Cartoon Characters (Right):</td>
|
||||
<td>
|
||||
#set ( $startCount = 1)
|
||||
#foreach( $item in $rightSideCartoonCharacters)
|
||||
$startCount.${item}
|
||||
#set ( $startCount = $startCount + 1)
|
||||
#end
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
#slabel ("label=Thoughts" "name=thoughts")
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
<tr>
|
||||
<td>Non Favourite Sports:</td>
|
||||
<td>
|
||||
<s:iterator value="nonFavouriteSports" status="stat">
|
||||
<s:iterator value="nonfavouriteSports" status="stat">
|
||||
<s:property value="%{#stat.count}" />.<s:property />
|
||||
</s:iterator>
|
||||
</td>
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<s:script type="text/javascript">
|
||||
<script type="text/javascript">
|
||||
/********************************************************************
|
||||
* JS just used on this page.
|
||||
* Usually this would be placed in a JS file
|
||||
@@ -196,6 +196,6 @@ function _handleValidationResult(form, errors) {
|
||||
$(window).bind('load', function() {
|
||||
$('form').bind('submit', ajaxFormValidation);
|
||||
});
|
||||
</s:script>
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,92 +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.
|
||||
*/
|
||||
-->
|
||||
<%@ taglib prefix="s" uri="/struts-tags" %>
|
||||
|
||||
<!-- START SNIPPET: dwrValidation -->
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>Struts2 Showcase - Validation - DWR</title>
|
||||
<s:head/>
|
||||
<s:script type='text/javascript' src='../dwr/engine.js'></s:script>
|
||||
<s:script type='text/javascript' src='../dwr/util.js'></s:script>
|
||||
<s:script type='text/javascript' src='../dwr/interface/validator.js'></s:script>
|
||||
<s:script type='text/javascript'>
|
||||
var dwrValidateReply = function(data) {
|
||||
var validationResult = '';
|
||||
for (index = 0; index < data.actionErrors.length; ++index) {
|
||||
validationResult += (data.actionErrors[index] + '. ');
|
||||
}
|
||||
for (index = 0; index < data.actionMessages.length; ++index) {
|
||||
validationResult += (data.actionMessages[index] + '. ');
|
||||
}
|
||||
if (typeof data.fieldErrors.name !== 'undefined') {
|
||||
for (index = 0; index < data.fieldErrors.name.length; ++index) {
|
||||
validationResult += (data.fieldErrors.name[index] + '. ');
|
||||
}
|
||||
}
|
||||
if (typeof data.fieldErrors.age !== 'undefined') {
|
||||
for (index = 0; index < data.fieldErrors.age.length; ++index) {
|
||||
validationResult += (data.fieldErrors.age[index] + '. ');
|
||||
}
|
||||
}
|
||||
if (validationResult === '') {
|
||||
$('form').submit();
|
||||
} else {
|
||||
dwr.util.setValue('validationResult', validationResult);
|
||||
}
|
||||
};
|
||||
function dwrFormValidation() {
|
||||
var postData = {};
|
||||
$('form').serializeArray().map(function (x) {
|
||||
postData[x.name] = x.value;
|
||||
});
|
||||
validator.doPost('/validation', 'quizDwr', postData, dwrValidateReply);
|
||||
return false;
|
||||
}
|
||||
</s:script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="page-header">
|
||||
<h1>DWR validation Example</h1>
|
||||
</div>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
|
||||
<s:form method="post">
|
||||
<s:textfield label="Name" name="name"/>
|
||||
<s:textfield label="Age" name="age"/>
|
||||
<s:textfield label="Favorite color" name="answer"/>
|
||||
<s:submit cssClass="btn btn-primary" onClick="return dwrFormValidation()"/>
|
||||
</s:form>
|
||||
<div id="validationResult" class="errorMessage"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<!-- END SNIPPET: dwrValidation -->
|
||||
|
||||
@@ -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,46 +26,49 @@
|
||||
<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');
|
||||
})
|
||||
</s:script>
|
||||
<script>
|
||||
$('#codeTab a').click(function (e) {
|
||||
e.preventDefault();
|
||||
$(this).tab('show');
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<?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
|
||||
@@ -17,64 +16,43 @@
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
-->
|
||||
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
|
||||
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
|
||||
version="3.1">
|
||||
<web-app id="WebApp_9" version="2.4"
|
||||
xmlns="http://java.sun.com/xml/ns/j2ee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
|
||||
|
||||
<display-name>Struts Showcase Application</display-name>
|
||||
|
||||
<filter>
|
||||
<filter-name>async</filter-name>
|
||||
<filter-class>org.apache.struts2.showcase.async.AsyncFilter</filter-class>
|
||||
<async-supported>true</async-supported>
|
||||
</filter>
|
||||
|
||||
|
||||
<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>
|
||||
<async-supported>true</async-supported>
|
||||
</filter>
|
||||
|
||||
<filter-mapping>
|
||||
<filter-name>async</filter-name>
|
||||
<url-pattern>/async/*</url-pattern>
|
||||
</filter-mapping>
|
||||
<filter>
|
||||
<filter-name>sitemesh</filter-name>
|
||||
<filter-class>com.opensymphony.sitemesh.webapp.SiteMeshFilter</filter-class>
|
||||
</filter>
|
||||
|
||||
<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>
|
||||
@@ -86,42 +64,35 @@
|
||||
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>
|
||||
<servlet-name>dwr</servlet-name>
|
||||
<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
|
||||
<servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
|
||||
<init-param>
|
||||
<param-name>debug</param-name>
|
||||
<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>
|
||||
|
||||
<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.-->
|
||||
<!-- 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>
|
||||
@@ -129,7 +100,7 @@
|
||||
<param-name>default_encoding</param-name>
|
||||
<param-value>UTF-8</param-value>
|
||||
</init-param>
|
||||
<load-on-startup>3</load-on-startup>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
|
||||
<servlet>
|
||||
@@ -139,7 +110,7 @@
|
||||
<param-name>default_encoding</param-name>
|
||||
<param-value>UTF-8</param-value>
|
||||
</init-param>
|
||||
<load-on-startup>4</load-on-startup>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
|
||||
<servlet-mapping>
|
||||
@@ -157,11 +128,6 @@
|
||||
<url-pattern>*.vm</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>strutsServlet</servlet-name>
|
||||
<url-pattern>/async/receiveNewMessages</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- END SNIPPET: dwr -->
|
||||
|
||||
<!-- SNIPPET START: example.velocity.filter.chain
|
||||
|
||||
@@ -1,120 +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 - Async Example</title>
|
||||
<script>
|
||||
function User () {
|
||||
this.lastIndex = 0;
|
||||
this.sendMessage = function(message) {
|
||||
$.ajax({
|
||||
async: false,
|
||||
url: "sendMessage",
|
||||
data: {
|
||||
message: message
|
||||
}
|
||||
});
|
||||
};
|
||||
this.receiveNewMessages = function() {
|
||||
$.ajax({
|
||||
url: "receiveNewMessages",
|
||||
context: this,
|
||||
data: {
|
||||
lastIndex: this.lastIndex
|
||||
},
|
||||
success: function (result) {
|
||||
if (result != null) {//result is null on timeout
|
||||
var msgs = $('#msgs');
|
||||
var messages = msgs.val();
|
||||
msgs.val(messages + result + '\n');
|
||||
this.lastIndex += result.length;
|
||||
}
|
||||
this.receiveNewMessages();
|
||||
}
|
||||
});
|
||||
};
|
||||
this.receiveNewMessages();
|
||||
}
|
||||
|
||||
var user;
|
||||
|
||||
function sendMessage() {
|
||||
var msg = $('#msg');
|
||||
var message = msg.val();
|
||||
if (message.length > 0) {
|
||||
user.sendMessage(message);
|
||||
msg.val('');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
$(function() {
|
||||
user = new User();
|
||||
});
|
||||
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="page-header">
|
||||
<h1>Async Example</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 async request processing.
|
||||
</p>
|
||||
<p>
|
||||
When you have a process that takes a long time, it can make your app not scalable under heavy load conditions.
|
||||
Scalability limitations include running out of memory or exhausting the pool of container threads.
|
||||
To create scalable web applications, you must ensure that no threads associated with a request
|
||||
are sitting idle, so the container can use them to process new requests.
|
||||
Asynchronous processing refers to assigning these blocking operations to a new thread and returning
|
||||
the thread associated with the request immediately to the container.
|
||||
<br/> Reference: <a href="https://docs.oracle.com/javaee/7/tutorial/servlets012.htm">Asynchronous Processing</a>
|
||||
<br/> An interesting and vital use case for the async request processing is server push.
|
||||
A good solution is to use the Servlet 3.0+ asynchronous feature.
|
||||
</p>
|
||||
|
||||
<br/>
|
||||
<h2>Example: A minimal chat room using server push</h2>
|
||||
<h3>Open current page in different tabs, browsers and computers then send messages.</h3>
|
||||
<h4>This is a minimal chat room which uses server push to retrieve new messages.
|
||||
It doesn't poll the server frequently to check if a new message is available to display.
|
||||
Instead it waits for the server to push back new messages. This approach has two obvious advantages:
|
||||
low-lag communication without requests being sent, and no waste of server resources and network bandwidth.</h4>
|
||||
<h5>Reference: <a href="https://www.javaworld.com/article/2077995/java-concurrency/java-concurrency-asynchronous-processing-support-in-servlet-3-0.html">
|
||||
Asynchronous processing support in Servlet 3.0</a></h5>
|
||||
<textarea id="msgs" cols="40" rows="5" title="messages" readonly></textarea><br/>
|
||||
<form>
|
||||
<input name="msg" id="msg" type="text" title="message" required />
|
||||
<input type="submit" value="Send" onclick="return sendMessage();" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -20,22 +20,11 @@
|
||||
*/
|
||||
package it.org.apache.struts2.showcase;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.gargoylesoftware.htmlunit.WebClient;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlPage;
|
||||
|
||||
public class ActionChainingTest {
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
try (final WebClient webClient = new WebClient()) {
|
||||
final HtmlPage page = webClient.getPage(ParameterUtils.getBaseUrl() + "/actionchaining/actionChain1!input");
|
||||
|
||||
final String pageAsText = page.asNormalizedText();
|
||||
Assert.assertTrue(pageAsText.contains("Action Chain 1 Property 1: Property Set In Action Chain 1"));
|
||||
Assert.assertTrue(pageAsText.contains("Action Chain 2 Property 1: Property Set in Action Chain 2"));
|
||||
Assert.assertTrue(pageAsText.contains("Action Chain 3 Property 1: Property set in Action Chain 3"));
|
||||
}
|
||||
public class ActionChainingTest extends ITBaseTest {
|
||||
public void test() {
|
||||
beginAt("/actionchaining/actionChain1!input");
|
||||
assertTextPresent("Action Chain 1 Property 1: Property Set In Action Chain 1");
|
||||
assertTextPresent("Action Chain 2 Property 1: Property Set in Action Chain 2");
|
||||
assertTextPresent("Action Chain 3 Property 1: Property set in Action Chain 3");
|
||||
}
|
||||
}
|
||||
|
||||
+5
-15
@@ -20,20 +20,10 @@
|
||||
*/
|
||||
package it.org.apache.struts2.showcase;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.gargoylesoftware.htmlunit.WebClient;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlPage;
|
||||
|
||||
public class ActionTagExampleTest {
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
try (final WebClient webClient = new WebClient()) {
|
||||
final HtmlPage page = webClient.getPage(ParameterUtils.getBaseUrl() + "/tags/ui/actionTagExample!input.action");
|
||||
|
||||
final String pageAsText = page.asNormalizedText();
|
||||
Assert.assertTrue(pageAsText.contains("This text is from the called class"));
|
||||
}
|
||||
public class ActionTagExampleTest extends ITBaseTest {
|
||||
public void test() {
|
||||
beginAt("/tags/ui/actionTagExample!input.action");
|
||||
assertTextPresent("This text is from the called class");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,52 +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.
|
||||
*/
|
||||
package it.org.apache.struts2.showcase;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.gargoylesoftware.htmlunit.WebClient;
|
||||
import com.gargoylesoftware.htmlunit.html.DomElement;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlForm;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlPage;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlTextInput;
|
||||
|
||||
public class AsyncTest {
|
||||
@Test
|
||||
public void testChatRoom() throws Exception {
|
||||
try (final WebClient webClient = new WebClient()) {
|
||||
final HtmlPage page = webClient.getPage(ParameterUtils.getBaseUrl() + "/async/index.html");
|
||||
|
||||
final HtmlForm form = page.getForms().get(0);
|
||||
|
||||
final HtmlTextInput textField = form.getInputByName("msg");
|
||||
textField.type("hello");
|
||||
|
||||
final HtmlSubmitInput button = form.getInputByValue("Send");
|
||||
final HtmlPage page2 = button.click();
|
||||
|
||||
Thread.sleep(4000);
|
||||
|
||||
final DomElement msgs = page2.getElementById("msgs");
|
||||
|
||||
Assert.assertEquals("hello", msgs.asNormalizedText());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,34 +20,17 @@
|
||||
*/
|
||||
package it.org.apache.struts2.showcase;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
public class CRUDTest extends ITBaseTest {
|
||||
public void testCreate() {
|
||||
beginAt("/skill/edit.action");
|
||||
|
||||
import com.gargoylesoftware.htmlunit.WebClient;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlForm;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlPage;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlTextInput;
|
||||
setTextField("currentSkill.name", "somename1");
|
||||
setTextField("currentSkill.description", "somedescription1");
|
||||
|
||||
public class CRUDTest {
|
||||
@Test
|
||||
public void testCreate() throws Exception {
|
||||
try (final WebClient webClient = new WebClient()) {
|
||||
final HtmlPage page = webClient.getPage(ParameterUtils.getBaseUrl() + "/skill/edit.action");
|
||||
submit();
|
||||
|
||||
final HtmlForm form = page.getForms().get(0);
|
||||
|
||||
final HtmlTextInput textField = form.getInputByName("currentSkill.name");
|
||||
textField.type("somename1");
|
||||
final HtmlTextInput textField2 = form.getInputByName("currentSkill.description");
|
||||
textField2.type("somedescription1");
|
||||
|
||||
final HtmlSubmitInput button = form.getInputByValue("Save");
|
||||
final HtmlPage page2 = button.click();
|
||||
final String page2Text = page2.asNormalizedText();
|
||||
|
||||
Assert.assertTrue(page2Text.contains("somename1"));
|
||||
Assert.assertTrue(page2Text.contains("somedescription1"));
|
||||
}
|
||||
beginAt("/skill/list.action");
|
||||
assertTextPresent("somename1");
|
||||
assertTextPresent("somedescription1");
|
||||
}
|
||||
}
|
||||
|
||||
+7
-19
@@ -20,24 +20,12 @@
|
||||
*/
|
||||
package it.org.apache.struts2.showcase;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.gargoylesoftware.htmlunit.WebClient;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlPage;
|
||||
|
||||
public class ComponentTagExampleTest {
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
try (final WebClient webClient = new WebClient()) {
|
||||
final HtmlPage page = webClient
|
||||
.getPage(ParameterUtils.getBaseUrl() + "/tags/ui/componentTagExample.action");
|
||||
|
||||
final String pageAsText = page.asNormalizedText();
|
||||
Assert.assertTrue(pageAsText.contains("Freemarker Custom Template - parameter 'paramName' - paramValue1"));
|
||||
Assert.assertTrue(pageAsText.contains("Freemarker Custom Template - parameter 'paramName' - paramValue4"));
|
||||
Assert.assertTrue(pageAsText.contains("JSP Custom Template - parameter 'paramName' - paramValue2"));
|
||||
Assert.assertTrue(pageAsText.contains("JSP Custom Template - parameter 'paramName' - paramValue3"));
|
||||
}
|
||||
public class ComponentTagExampleTest extends ITBaseTest {
|
||||
public void test() {
|
||||
beginAt("/tags/ui/componentTagExample.jsp");
|
||||
assertTextPresent("Freemarker Custom Template - parameter 'paramName' - paramValue1");
|
||||
assertTextPresent("Freemarker Custom Template - parameter 'paramName' - paramValue4");
|
||||
assertTextPresent("JSP Custom Template - parameter 'paramName' - paramValue2");
|
||||
assertTextPresent("JSP Custom Template - parameter 'paramName' - paramValue3");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,82 +20,48 @@
|
||||
*/
|
||||
package it.org.apache.struts2.showcase;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
public class ConversionTest extends ITBaseTest {
|
||||
public void testList() {
|
||||
beginAt("/conversion/enterPersonsInfo.action");
|
||||
setTextField("persons[0].name", "name0");
|
||||
setTextField("persons[0].age", "0");
|
||||
setTextField("persons[1].name", "name1");
|
||||
setTextField("persons[1].age", "1");
|
||||
setTextField("persons[2].name", "name2");
|
||||
setTextField("persons[2].age", "2");
|
||||
|
||||
import com.gargoylesoftware.htmlunit.WebClient;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlForm;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlPage;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput;
|
||||
submit();
|
||||
|
||||
public class ConversionTest {
|
||||
@Test
|
||||
public void testList() throws Exception {
|
||||
try (final WebClient webClient = new WebClient()) {
|
||||
final HtmlPage page = webClient
|
||||
.getPage(ParameterUtils.getBaseUrl() + "/conversion/enterPersonsInfo.action");
|
||||
|
||||
final HtmlForm form = page.getForms().get(0);
|
||||
|
||||
form.getInputByName("persons[0].name").type("name0");
|
||||
form.getInputByName("persons[0].age").type("0");
|
||||
form.getInputByName("persons[1].name").type("name1");
|
||||
form.getInputByName("persons[1].age").type("1");
|
||||
form.getInputByName("persons[2].name").type("name2");
|
||||
form.getInputByName("persons[2].age").type("2");
|
||||
|
||||
final HtmlSubmitInput button = form.getInputByValue("Submit");
|
||||
final HtmlPage page2 = button.click();
|
||||
final String page2Text = page2.asNormalizedText();
|
||||
|
||||
Assert.assertTrue(page2Text.contains("SET 0 Name: name0"));
|
||||
Assert.assertTrue(page2Text.contains("SET 0 Age: 0"));
|
||||
Assert.assertTrue(page2Text.contains("SET 1 Name: name1"));
|
||||
Assert.assertTrue(page2Text.contains("SET 1 Age: 1"));
|
||||
Assert.assertTrue(page2Text.contains("SET 2 Name: name2"));
|
||||
Assert.assertTrue(page2Text.contains("SET 2 Age: 2"));
|
||||
}
|
||||
assertTextPresent("SET 0 Name: name0");
|
||||
assertTextPresent("SET 0 Age: 0");
|
||||
assertTextPresent("SET 1 Name: name1");
|
||||
assertTextPresent("SET 1 Age: 1");
|
||||
assertTextPresent("SET 2 Name: name2");
|
||||
assertTextPresent("SET 2 Age: 2");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSet() throws Exception {
|
||||
try (final WebClient webClient = new WebClient()) {
|
||||
final HtmlPage page = webClient
|
||||
.getPage(ParameterUtils.getBaseUrl() + "/conversion/enterAddressesInfo.action");
|
||||
public void testSet() {
|
||||
beginAt("/conversion/enterAddressesInfo.action");
|
||||
setTextField("addresses('id0').address", "address0");
|
||||
setTextField("addresses('id1').address", "address1");
|
||||
setTextField("addresses('id2').address", "address2");
|
||||
|
||||
final HtmlForm form = page.getForms().get(0);
|
||||
submit();
|
||||
|
||||
form.getInputByName("addresses('id0').address").type("address0");
|
||||
form.getInputByName("addresses('id1').address").type("address1");
|
||||
form.getInputByName("addresses('id2').address").type("address2");
|
||||
|
||||
final HtmlSubmitInput button = form.getInputByValue("Submit");
|
||||
final HtmlPage page2 = button.click();
|
||||
final String page2Text = page2.asNormalizedText();
|
||||
|
||||
Assert.assertTrue(page2Text.contains("id0 -> address0"));
|
||||
Assert.assertTrue(page2Text.contains("id1 -> address1"));
|
||||
Assert.assertTrue(page2Text.contains("id2 -> address2"));
|
||||
}
|
||||
assertTextPresent("id0 -> address0");
|
||||
assertTextPresent("id1 -> address1");
|
||||
assertTextPresent("id2 -> address2");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEnum() throws Exception {
|
||||
try (final WebClient webClient = new WebClient()) {
|
||||
final HtmlPage page = webClient
|
||||
.getPage(ParameterUtils.getBaseUrl() + "/conversion/enterOperationEnumInfo.action");
|
||||
public void testEnum() {
|
||||
beginAt("/conversion/enterOperationEnumInfo.action");
|
||||
checkCheckbox("selectedOperations", "ADD");
|
||||
checkCheckbox("selectedOperations", "MINUS");
|
||||
|
||||
final HtmlForm form = page.getForms().get(0);
|
||||
submit();
|
||||
|
||||
form.getInputByValue("ADD").setChecked(true);
|
||||
form.getInputByValue("MINUS").setChecked(true);
|
||||
|
||||
final HtmlSubmitInput button = form.getInputByValue("Submit");
|
||||
final HtmlPage page2 = button.click();
|
||||
final String page2Text = page2.asNormalizedText();
|
||||
|
||||
Assert.assertTrue(page2Text.contains("ADD"));
|
||||
Assert.assertTrue(page2Text.contains("MINUS"));
|
||||
}
|
||||
assertTextPresent("ADD");
|
||||
assertTextPresent("MINUS");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,56 +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.
|
||||
*/
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,35 +20,16 @@
|
||||
*/
|
||||
package it.org.apache.struts2.showcase;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
public class ExecAndWaitTest extends ITBaseTest {
|
||||
public void testNodelay() throws InterruptedException {
|
||||
beginAt("/wait/example1.jsp");
|
||||
|
||||
import com.gargoylesoftware.htmlunit.WebClient;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlForm;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlPage;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlTextInput;
|
||||
setTextField("time", "7000");
|
||||
submit();
|
||||
assertTextPresent("We are processing your request. Please wait.");
|
||||
|
||||
public class ExecAndWaitTest {
|
||||
@Test
|
||||
public void testNodelay() throws Exception {
|
||||
try (final WebClient webClient = new WebClient()) {
|
||||
final HtmlPage page = webClient.getPage(ParameterUtils.getBaseUrl() + "/wait/example1.action");
|
||||
|
||||
final HtmlForm form = page.getForms().get(0);
|
||||
|
||||
final HtmlTextInput textField = form.getInputByName("time");
|
||||
textField.type("7000");
|
||||
|
||||
final HtmlSubmitInput button = form.getInputByValue("submit");
|
||||
final HtmlPage page2 = button.click();
|
||||
|
||||
Assert.assertTrue(page2.asNormalizedText().contains("We are processing your request. Please wait."));
|
||||
|
||||
// hit it again
|
||||
final HtmlPage page3 = webClient
|
||||
.getPage(ParameterUtils.getBaseUrl() + "/wait/longProcess1.action?time=1000");
|
||||
Assert.assertTrue(page3.asNormalizedText().contains("We are processing your request. Please wait."));
|
||||
}
|
||||
//hit it again
|
||||
beginAt("/wait/longProcess1.action?time=1000");
|
||||
assertTextPresent("We are processing your request. Please wait.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,51 +20,21 @@
|
||||
*/
|
||||
package it.org.apache.struts2.showcase;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.MalformedURLException;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
public class FileDownloadTest extends ITBaseTest {
|
||||
public void testImage() throws InterruptedException, MalformedURLException {
|
||||
beginAt("/filedownload/download.action");
|
||||
|
||||
import com.gargoylesoftware.htmlunit.Page;
|
||||
import com.gargoylesoftware.htmlunit.WebClient;
|
||||
|
||||
public class FileDownloadTest {
|
||||
@Test
|
||||
public void testImage() throws Exception {
|
||||
try (final WebClient webClient = new WebClient()) {
|
||||
final Page page = webClient.getPage(ParameterUtils.getBaseUrl() + "/filedownload/download.action");
|
||||
|
||||
URL url = new URL(
|
||||
"https://gitbox.apache.org/repos/asf?p=struts.git;a=blob_plain;f=apps/showcase/src/main/webapp/images/struts.gif;hb=HEAD");
|
||||
|
||||
Assert.assertTrue(areFilesEqual(url.openStream(), page.getWebResponse().getContentAsStream()));
|
||||
}
|
||||
URL url = new URL("http://svn.apache.org/repos/asf/struts/struts2/trunk/apps/showcase/src/main/webapp/images/struts.gif");
|
||||
assertDownloadedFileEquals(url);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testZip() throws Exception {
|
||||
try (final WebClient webClient = new WebClient()) {
|
||||
final Page page = webClient.getPage(ParameterUtils.getBaseUrl() + "/filedownload/download2.action");
|
||||
public void testZip() throws InterruptedException, MalformedURLException {
|
||||
beginAt("/filedownload/download2.action");
|
||||
|
||||
URL url = new URL(
|
||||
"https://gitbox.apache.org/repos/asf?p=struts.git;a=blob_plain;f=apps/showcase/src/main/webapp/images/struts-gif.zip;hb=HEAD");
|
||||
|
||||
Assert.assertTrue(areFilesEqual(url.openStream(), page.getWebResponse().getContentAsStream()));
|
||||
}
|
||||
}
|
||||
|
||||
private boolean areFilesEqual(InputStream i1, InputStream i2) throws IOException {
|
||||
// read and compare bytes pair-wise
|
||||
int b1, b2;
|
||||
do {
|
||||
b1 = i1.read();
|
||||
b2 = i2.read();
|
||||
} while (b1 == b2 && b1 != -1 && b2 != -1);
|
||||
i1.close();
|
||||
i2.close();
|
||||
// true only if end of file is reached for both
|
||||
return (b1 == -1) && (b2 == -1);
|
||||
URL url = new URL("http://svn.apache.org/repos/asf/struts/struts2/trunk/apps/showcase/src/main/webapp/images/struts-gif.zip");
|
||||
assertDownloadedFileEquals(url);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,54 +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.
|
||||
*/
|
||||
package it.org.apache.struts2.showcase;
|
||||
|
||||
import com.gargoylesoftware.htmlunit.WebClient;
|
||||
import com.gargoylesoftware.htmlunit.html.DomElement;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlFileInput;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlForm;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlInput;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlPage;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class FileUploadTest {
|
||||
|
||||
@Test
|
||||
public void testEmptyFile() throws Exception {
|
||||
try (final WebClient webClient = new WebClient()) {
|
||||
final HtmlPage page = webClient.getPage(ParameterUtils.getBaseUrl() + "/fileupload/doUpload.action");
|
||||
final HtmlForm form = page.getFormByName("doUpload");
|
||||
HtmlInput captionInput = form.getInputByName("caption");
|
||||
HtmlFileInput uploadInput = form.getInputByName("upload");
|
||||
captionInput.type("some caption");
|
||||
File tempFile = File.createTempFile("testEmptyFile", ".tmp");
|
||||
tempFile.deleteOnExit();
|
||||
uploadInput.setValueAttribute(tempFile.getAbsolutePath());
|
||||
final HtmlSubmitInput button = form.getInputByValue("Submit");
|
||||
final HtmlPage resultPage = button.click();
|
||||
DomElement errorMessage = resultPage.getFirstByXPath("//span[@class='errorMessage']");
|
||||
Assert.assertNotNull(errorMessage);
|
||||
Assert.assertEquals("File cannot be empty", errorMessage.getVisibleText());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+15
-30
@@ -20,40 +20,25 @@
|
||||
*/
|
||||
package it.org.apache.struts2.showcase;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
import com.gargoylesoftware.htmlunit.WebClient;
|
||||
import com.gargoylesoftware.htmlunit.html.DomElement;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlPage;
|
||||
public class FreeMarkerManagerTest extends ITBaseTest {
|
||||
public void testCustomManager() {
|
||||
beginAt("/freemarker/customFreemarkerManagerDemo.action");
|
||||
|
||||
public class FreeMarkerManagerTest {
|
||||
@Test
|
||||
public void testCustomManager() throws Exception {
|
||||
try (final WebClient webClient = new WebClient()) {
|
||||
final HtmlPage page = webClient
|
||||
.getPage(ParameterUtils.getBaseUrl() + "/freemarker/customFreemarkerManagerDemo.action");
|
||||
String date = getElementTextByXPath("//*[@id='todaysDate']");
|
||||
assertNotNull(date);
|
||||
assertTrue(date.length() > 0);
|
||||
|
||||
final DomElement date = page.getElementById("todaysDate");
|
||||
Assert.assertNotNull(date);
|
||||
Assert.assertTrue(date.asNormalizedText().length() > 0);
|
||||
|
||||
final DomElement time = page.getElementById("timeNow");
|
||||
Assert.assertNotNull(time);
|
||||
Assert.assertTrue(time.asNormalizedText().length() > 0);
|
||||
}
|
||||
String time = getElementTextByXPath("//*[@id='timeNow']");
|
||||
assertNotNull(time);
|
||||
assertTrue(time.length() > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTags() throws Exception {
|
||||
try (final WebClient webClient = new WebClient()) {
|
||||
final HtmlPage page = webClient.getPage(ParameterUtils.getBaseUrl() + "/freemarker/standardTags.action");
|
||||
|
||||
final DomElement date = page.getElementById("test_name");
|
||||
Assert.assertNotNull(date);
|
||||
|
||||
final DomElement time = page.getElementById("test");
|
||||
Assert.assertNotNull(time);
|
||||
}
|
||||
public void testTags() {
|
||||
beginAt("/freemarker/standardTags.action");
|
||||
assertElementPresent("test_name");
|
||||
assertElementPresent("test_");
|
||||
}
|
||||
}
|
||||
|
||||
+8
-9
@@ -1,4 +1,6 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* 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,16 +18,13 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.struts2.action;
|
||||
package it.org.apache.struts2.showcase;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import net.sourceforge.jwebunit.junit.WebTestCase;
|
||||
|
||||
/**
|
||||
* For components that have a dependence on the Servlet context.
|
||||
*
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public interface ServletContextAware {
|
||||
public abstract class ITBaseTest extends WebTestCase {
|
||||
|
||||
void withServletContext(ServletContext context);
|
||||
public void setUp() throws Exception {
|
||||
getTestContext().setBaseUrl(ParameterUtils.getBaseUrl());
|
||||
}
|
||||
}
|
||||
@@ -1,55 +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.
|
||||
*/
|
||||
package it.org.apache.struts2.showcase;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
|
||||
import com.gargoylesoftware.htmlunit.WebClient;
|
||||
|
||||
public class StaticContentTest {
|
||||
|
||||
@Test
|
||||
public void testInvalidRersources1() throws Exception {
|
||||
try (final WebClient webClient = new WebClient()) {
|
||||
try {
|
||||
webClient.getPage(ParameterUtils.getBaseUrl() + "/struts..");
|
||||
Assert.fail("Previous request should have failed");
|
||||
} catch (FailingHttpStatusCodeException e) {
|
||||
Assert.assertEquals("Not Found", e.getStatusMessage());
|
||||
Assert.assertEquals(404, e.getStatusCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidRersources2() throws Exception {
|
||||
try (final WebClient webClient = new WebClient()) {
|
||||
try {
|
||||
webClient.getPage(ParameterUtils.getBaseUrl() + "/static/..%252f");
|
||||
Assert.fail("Previous request should have failed");
|
||||
} catch (FailingHttpStatusCodeException e) {
|
||||
Assert.assertEquals("Not Found", e.getStatusMessage());
|
||||
Assert.assertEquals(404, e.getStatusCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,56 +20,36 @@
|
||||
*/
|
||||
package it.org.apache.struts2.showcase;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
public class UITagExampleTest extends ITBaseTest {
|
||||
public void testInputForm() {
|
||||
setScriptingEnabled(false);
|
||||
beginAt("/tags/ui/example!input.action");
|
||||
assertFormPresent("exampleSubmit");
|
||||
// text box
|
||||
assertFormElementPresent("name");
|
||||
// textarea
|
||||
assertFormElementPresent("bio");
|
||||
// select
|
||||
assertFormElementPresent("favouriteColor");
|
||||
// checkbox list
|
||||
assertFormElementPresent("friends");
|
||||
// checkbox
|
||||
assertFormElementPresent("legalAge");
|
||||
|
||||
import com.gargoylesoftware.htmlunit.WebClient;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlCheckBoxInput;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlForm;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlPage;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlSelect;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlTextArea;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlTextInput;
|
||||
// set fields
|
||||
setTextField("name", "name");
|
||||
setTextField("bio", "bio");
|
||||
selectOption("favouriteColor", "Red");
|
||||
checkCheckbox("friends", "Patrick");
|
||||
checkCheckbox("friends", "Jason");
|
||||
checkCheckbox("legalAge");
|
||||
|
||||
public class UITagExampleTest {
|
||||
@Test
|
||||
public void testInputForm() throws Exception {
|
||||
try (final WebClient webClient = new WebClient()) {
|
||||
final HtmlPage page = webClient.getPage(ParameterUtils.getBaseUrl() + "/tags/ui/example!input.action");
|
||||
submit();
|
||||
|
||||
final HtmlForm form = page.getFormByName("exampleSubmit");
|
||||
Assert.assertNotNull(form);
|
||||
|
||||
final HtmlTextInput textField = form.getInputByName("name");
|
||||
final HtmlTextArea textField2 = form.getTextAreaByName("bio");
|
||||
final HtmlSelect textField3 = form.getSelectByName("favouriteColor");
|
||||
final HtmlCheckBoxInput textField4 = form.getInputByValue("Patrick");
|
||||
final HtmlCheckBoxInput textField41 = form.getInputByValue("Jason");
|
||||
final HtmlCheckBoxInput textField5 = form.getInputByName("legalAge");
|
||||
|
||||
Assert.assertNotNull(textField);
|
||||
Assert.assertNotNull(textField2);
|
||||
Assert.assertNotNull(textField3);
|
||||
Assert.assertNotNull(textField4);
|
||||
Assert.assertNotNull(textField41);
|
||||
Assert.assertNotNull(textField5);
|
||||
|
||||
textField.type("name");
|
||||
textField2.type("bio");
|
||||
textField3.setSelectedAttribute("Red", true);
|
||||
textField4.setChecked(true);
|
||||
textField41.setChecked(true);
|
||||
textField5.setChecked(true);
|
||||
|
||||
final HtmlSubmitInput button = form.getInputByValue("Submit");
|
||||
final HtmlPage page2 = button.click();
|
||||
|
||||
Assert.assertEquals("name", page2.getElementById("name").asNormalizedText());
|
||||
Assert.assertEquals("bio", page2.getElementById("bio").asNormalizedText());
|
||||
Assert.assertEquals("Red", page2.getElementById("favouriteColor").asNormalizedText());
|
||||
Assert.assertEquals("[Patrick, Jason]", page2.getElementById("friends").asNormalizedText());
|
||||
Assert.assertEquals("true", page2.getElementById("legalAge").asNormalizedText());
|
||||
}
|
||||
assertTextInElement("name", "name");
|
||||
assertTextInElement("bio", "bio");
|
||||
assertTextInElement("favouriteColor", "Red");
|
||||
assertTextInElement("friends", "[Patrick, Jason]");
|
||||
assertTextInElement("legalAge", "true");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,44 +20,27 @@
|
||||
*/
|
||||
package it.org.apache.struts2.showcase;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
public class ValidationTest extends ITBaseTest {
|
||||
public void testFieldValidators() {
|
||||
beginAt("/validation/showFieldValidatorsExamples.action");
|
||||
|
||||
import com.gargoylesoftware.htmlunit.WebClient;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlForm;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlPage;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput;
|
||||
setTextField("integerValidatorField", "nonint");
|
||||
setTextField("dateValidatorField", "nondate");
|
||||
setTextField("emailValidatorField", "!@@#%");
|
||||
setTextField("urlValidatorField", "!@@#%");
|
||||
setTextField("stringLengthValidatorField", "a");
|
||||
setTextField("regexValidatorField", "abc");
|
||||
setTextField("fieldExpressionValidatorField", "abc");
|
||||
|
||||
public class ValidationTest {
|
||||
@Test
|
||||
public void testFieldValidators() throws Exception {
|
||||
try (final WebClient webClient = new WebClient()) {
|
||||
final HtmlPage page = webClient
|
||||
.getPage(ParameterUtils.getBaseUrl() + "/validation/showFieldValidatorsExamples.action");
|
||||
submit();
|
||||
|
||||
final HtmlForm form = page.getForms().get(0);
|
||||
|
||||
form.getInputByName("integerValidatorField").type("nonint");
|
||||
form.getInputByName("dateValidatorField").type("nondate");
|
||||
form.getInputByName("emailValidatorField").type("!@@#%");
|
||||
form.getInputByName("urlValidatorField").type("!@@#%");
|
||||
form.getInputByName("stringLengthValidatorField").type("a");
|
||||
form.getInputByName("regexValidatorField").type("abc");
|
||||
form.getInputByName("fieldExpressionValidatorField").type("abc");
|
||||
|
||||
final HtmlSubmitInput button = form.getInputByValue("Submit");
|
||||
final HtmlPage page2 = button.click();
|
||||
final String page2Text = page2.asNormalizedText();
|
||||
|
||||
Assert.assertTrue(page2Text.contains("Invalid field value for field \"dateValidatorField\""));
|
||||
Assert.assertTrue(page2Text.contains("Invalid field value for field \"integerValidatorField\""));
|
||||
Assert.assertTrue(page2Text.contains("required and must be string"));
|
||||
Assert.assertTrue(page2Text.contains("must be a valid email if supplied"));
|
||||
Assert.assertTrue(page2Text.contains("must be a valid url if supplied"));
|
||||
Assert.assertTrue(
|
||||
page2Text.contains("must be a String of a specific greater than 1 less than 5 if specified"));
|
||||
Assert.assertTrue(page2Text.contains("regexValidatorField must match a regexp (.*\\.txt) if specified"));
|
||||
Assert.assertTrue(page2Text.contains("must be the same as the Required Validator Field if specified"));
|
||||
}
|
||||
assertTextPresent("Invalid field value for field \"dateValidatorField\"");
|
||||
assertTextPresent("Invalid field value for field \"integerValidatorField\"");
|
||||
assertTextPresent("required and must be string");
|
||||
assertTextPresent("must be a valid email if supplied");
|
||||
assertTextPresent("must be a valid url if supplied ");
|
||||
assertTextPresent("must be a String of a specific greater than 1 less than 5 if specified ");
|
||||
assertTextPresent("regexValidatorField must match a regexp (.*\\.txt) if specified ");
|
||||
assertTextPresent("must be the same as the Required Validator Field if specified ");
|
||||
}
|
||||
}
|
||||
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.staticcontent;
|
||||
|
||||
import it.org.apache.struts2.showcase.ITBaseTest;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import net.sourceforge.jwebunit.exception.TestingEngineResponseException;
|
||||
|
||||
public class StaticContentTest extends ITBaseTest {
|
||||
|
||||
public void testInvalidRersources1() throws IOException {
|
||||
try {
|
||||
beginAt("/struts..");
|
||||
fail("Previous request should have failed");
|
||||
} catch (TestingEngineResponseException ex) {
|
||||
// ok
|
||||
}
|
||||
}
|
||||
|
||||
public void testInvalidRersources2() throws IOException {
|
||||
try {
|
||||
beginAt("/struts/..%252f");
|
||||
fail("Previous request should have failed");
|
||||
} catch (TestingEngineResponseException ex) {
|
||||
// ok
|
||||
}
|
||||
}
|
||||
|
||||
/*public void testInvalidRersources3() throws IOException {
|
||||
try {
|
||||
beginAt("/struts/..%252f..%252f..%252fWEB-INF/classes/org/apache/struts2/showcase/action/EmployeeAction.class/");
|
||||
fail("Previous request should have failed");
|
||||
} catch (TestingEngineResponseException ex) {
|
||||
// ok
|
||||
}
|
||||
}*/
|
||||
}
|
||||
+6
-1
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-parent</artifactId>
|
||||
<version>6.0.3</version>
|
||||
<version>2.5.26</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-assembly</artifactId>
|
||||
@@ -204,6 +204,11 @@
|
||||
<artifactId>struts2-rest-plugin</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-sitegraph-plugin</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-sitemesh-plugin</artifactId>
|
||||
|
||||
@@ -193,6 +193,10 @@
|
||||
<directory>../plugins/rest/target/apidocs</directory>
|
||||
<outputDirectory>docs/struts2-plugins/struts2-rest-plugin/apidocs</outputDirectory>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>../plugins/sitegraph/target/apidocs</directory>
|
||||
<outputDirectory>docs/struts2-plugins/struts2-sitegraph-plugin/apidocs</outputDirectory>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>../plugins/sitemesh/target/apidocs</directory>
|
||||
<outputDirectory>docs/struts2-plugins/struts2-sitemesh-plugin/apidocs</outputDirectory>
|
||||
@@ -209,10 +213,6 @@
|
||||
<directory>../plugins/tiles/target/apidocs</directory>
|
||||
<outputDirectory>docs/struts2-plugins/struts2-tiles-plugin/apidocs</outputDirectory>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>../plugins/velocity/target/apidocs</directory>
|
||||
<outputDirectory>docs/struts2-plugins/struts2-velocity-plugin/apidocs</outputDirectory>
|
||||
</fileSet>
|
||||
|
||||
<!-- bundles -->
|
||||
<fileSet>
|
||||
|
||||
@@ -128,6 +128,10 @@
|
||||
<directory>../plugins/rest/target/apidocs</directory>
|
||||
<outputDirectory>docs/struts2-plugins/struts2-rest-plugin/apidocs</outputDirectory>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>../plugins/sitegraph/target/apidocs</directory>
|
||||
<outputDirectory>docs/struts2-plugins/struts2-sitegraph-plugin/apidocs</outputDirectory>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>../plugins/sitemesh/target/apidocs</directory>
|
||||
<outputDirectory>docs/struts2-plugins/struts2-sitemesh-plugin/apidocs</outputDirectory>
|
||||
|
||||
@@ -38,8 +38,9 @@
|
||||
<include>org.apache.commons:commons-lang3</include>
|
||||
<include>org.apache.logging.log4j:log4j-api</include>
|
||||
<include>ognl:ognl</include>
|
||||
<include>org.javassist:javassist</include>
|
||||
<include>commons-fileupload:commons-fileupload</include>
|
||||
<include>org.apache.commons:commons-io</include>
|
||||
<include>commons-io:commons-io</include>
|
||||
</includes>
|
||||
</dependencySet>
|
||||
</dependencySets>
|
||||
|
||||
@@ -11,6 +11,7 @@ ANTLR (http://www.antlr.org/).
|
||||
Classworlds (http://classworlds.codehaus.org/).
|
||||
EZMorph (http://ezmorph.sourceforge.net/)
|
||||
FreeMarker (http://freemarker.org/).
|
||||
JSON-lib (http://json-lib.sourceforge.net/).
|
||||
OGNL (http://www.opensymphony.com/ognl/).
|
||||
Plexus (http://plexus.codehaus.org/).
|
||||
SiteMesh (http://www.opensymphony.com/sitemesh/).
|
||||
|
||||
+10
-14
@@ -25,11 +25,12 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts-master</artifactId>
|
||||
<version>14</version>
|
||||
<version>9</version>
|
||||
<relativePath>../struts-master</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-bom</artifactId>
|
||||
<version>6.0.3</version>
|
||||
<version>2.5.26</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>Struts 2 Bill of Materials</name>
|
||||
@@ -44,7 +45,7 @@
|
||||
</licenses>
|
||||
|
||||
<properties>
|
||||
<struts-version.version>6.0.3</struts-version.version>
|
||||
<struts-version.version>2.5.26</struts-version.version>
|
||||
<maven.site.skip>true</maven.site.skip>
|
||||
<maven.site.deploy.skip>true</maven.site.deploy.skip>
|
||||
</properties>
|
||||
@@ -56,11 +57,6 @@
|
||||
<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>
|
||||
@@ -156,6 +152,11 @@
|
||||
<artifactId>struts2-rest-plugin</artifactId>
|
||||
<version>${struts-version.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-sitegraph-plugin</artifactId>
|
||||
<version>${struts-version.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-sitemesh-plugin</artifactId>
|
||||
@@ -176,16 +177,11 @@
|
||||
<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_3</tag>
|
||||
<tag>STRUTS_2_5_26</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.3</version>
|
||||
<version>2.5.26</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-osgi-admin-bundle</artifactId>
|
||||
<packaging>bundle</packaging>
|
||||
<name>DEPRECATED: Struts 2 OSGi Admin Bundle - since 6.0.0</name>
|
||||
<name>Struts 2 OSGi Admin Bundle</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
@@ -37,7 +37,7 @@
|
||||
<artifactId>struts2-osgi-plugin</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
@@ -48,7 +48,7 @@
|
||||
<instructions>
|
||||
<manifestLocation>META-INF</manifestLocation>
|
||||
<Struts2-Enabled>true</Struts2-Enabled>
|
||||
<Import-Package>*</Import-Package>
|
||||
<Import-Package>*,com.opensymphony.xwork2</Import-Package>
|
||||
<Export-Package>org.apache.struts2.osgi.admin*</Export-Package>
|
||||
<Spring-Context>*;create-asynchronously:=false</Spring-Context>
|
||||
</instructions>
|
||||
|
||||
+24
-25
@@ -28,7 +28,7 @@ import com.opensymphony.xwork2.inject.Inject;
|
||||
import org.apache.struts2.osgi.BundleAccessor;
|
||||
import org.apache.struts2.osgi.host.OsgiHost;
|
||||
import org.apache.struts2.osgi.StrutsOsgiListener;
|
||||
import org.apache.struts2.action.ServletContextAware;
|
||||
import org.apache.struts2.util.ServletContextAware;
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.BundleException;
|
||||
|
||||
@@ -126,11 +126,12 @@ public class BundlesAction extends ActionSupport implements ServletContextAware
|
||||
List<PackageConfig> pkgs = new ArrayList<>();
|
||||
Bundle bundle = getBundle();
|
||||
if (bundle.getState() == Bundle.ACTIVE) {
|
||||
bundleAccessor.getPackagesByBundle(bundle).stream().map(
|
||||
name -> configuration.getPackageConfig(name)).filter(
|
||||
packageConfig -> (packageConfig != null)).forEachOrdered(packageConfig -> {
|
||||
pkgs.add(packageConfig);
|
||||
});
|
||||
for (String name : bundleAccessor.getPackagesByBundle(bundle)) {
|
||||
PackageConfig packageConfig = configuration.getPackageConfig(name);
|
||||
if (packageConfig != null) {
|
||||
pkgs.add(packageConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
return pkgs;
|
||||
}
|
||||
@@ -141,14 +142,17 @@ public class BundlesAction extends ActionSupport implements ServletContextAware
|
||||
|
||||
public Collection<Bundle> getBundles() {
|
||||
List<Bundle> bundles = new ArrayList(osgiHost.getBundles().values());
|
||||
Collections.sort(bundles, (Bundle bundle1, Bundle bundle2) -> {
|
||||
boolean bundle1StrutsEnabled = isStrutsEnabled(bundle1);
|
||||
boolean bundle2StrutsEnabled = isStrutsEnabled(bundle2);
|
||||
Collections.sort(bundles, new Comparator<Bundle>() {
|
||||
@Override
|
||||
public int compare(Bundle bundle1, Bundle bundle2) {
|
||||
boolean bundle1StrutsEnabled = isStrutsEnabled(bundle1);
|
||||
boolean bundle2StrutsEnabled = isStrutsEnabled(bundle2);
|
||||
|
||||
if ((bundle1StrutsEnabled && bundle2StrutsEnabled) || (!bundle1StrutsEnabled && !bundle2StrutsEnabled)) {
|
||||
return bundle1.getSymbolicName().compareTo(bundle2.getSymbolicName());
|
||||
} else {
|
||||
return bundle1StrutsEnabled ? -1 : 1;
|
||||
if ((bundle1StrutsEnabled && bundle2StrutsEnabled) || (!bundle1StrutsEnabled && !bundle2StrutsEnabled)) {
|
||||
return bundle1.getSymbolicName().compareTo(bundle2.getSymbolicName());
|
||||
} else {
|
||||
return bundle1StrutsEnabled ? -1 : 1;
|
||||
}
|
||||
}
|
||||
});
|
||||
return bundles;
|
||||
@@ -183,17 +187,12 @@ public class BundlesAction extends ActionSupport implements ServletContextAware
|
||||
return false;
|
||||
}
|
||||
|
||||
if (val != null) {
|
||||
switch (val) {
|
||||
case "start":
|
||||
return state == Bundle.RESOLVED;
|
||||
case "stop":
|
||||
return state == Bundle.ACTIVE;
|
||||
case "update":
|
||||
return state == Bundle.ACTIVE || state == Bundle.INSTALLED || state == Bundle.RESOLVED;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if ("start".equals(val)) {
|
||||
return state == Bundle.RESOLVED;
|
||||
} else if ("stop".equals(val)) {
|
||||
return state == Bundle.ACTIVE;
|
||||
} else if ("update".equals(val)) {
|
||||
return state == Bundle.ACTIVE || state == Bundle.INSTALLED || state == Bundle.RESOLVED;
|
||||
}
|
||||
throw new IllegalArgumentException("Invalid state");
|
||||
}
|
||||
@@ -209,7 +208,7 @@ public class BundlesAction extends ActionSupport implements ServletContextAware
|
||||
}
|
||||
|
||||
@Override
|
||||
public void withServletContext(ServletContext servletContext) {
|
||||
public void setServletContext(ServletContext servletContext) {
|
||||
osgiHost = (OsgiHost) servletContext.getAttribute(StrutsOsgiListener.OSGI_HOST);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,9 +91,8 @@ public class ShellAction extends ActionSupport implements BundleContextAware {
|
||||
out.println("Attempting to execute command: " + commandLine);
|
||||
shellService.executeCommand(commandLine, out, err);
|
||||
}
|
||||
else {
|
||||
else
|
||||
err.println("Apache Felix Shell service is not installed");
|
||||
}
|
||||
}
|
||||
|
||||
private ShellService getShellService(PrintStream out) {
|
||||
|
||||
@@ -22,13 +22,13 @@
|
||||
<head>
|
||||
<title>OSGi Console</title>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="<@s.url value="${parameters.staticContentPath}/css/shell.css" />" />
|
||||
<link rel="stylesheet" type="text/css" href="<@s.url value="${parameters.staticContentPath}/css/main.css" />" />
|
||||
<link rel="stylesheet" type="text/css" href="<@s.url value="${parameters.staticContentPath}/css/redmond/jquery-ui-1.12.1.redmond.css" />" />
|
||||
<link rel="stylesheet" type="text/css" href="<@s.url value="/static/css/shell.css" />" />
|
||||
<link rel="stylesheet" type="text/css" href="<@s.url value="/static/css/main.css" />" />
|
||||
<link rel="stylesheet" type="text/css" href="<@s.url value="/static/css/redmond/jquery-ui-1.12.1.redmond.css" />" />
|
||||
|
||||
<script src="<@s.url value="${parameters.staticContentPath}/js/shell.js" />"></script>
|
||||
<script src="<@s.url value="${parameters.staticContentPath}/js/jquery-1.12.4.min.js" />"></script>
|
||||
<script src="<@s.url value="${parameters.staticContentPath}/js/jquery-ui-1.12.1.min.js" />"></script>
|
||||
<script src="<@s.url value="/static/js/shell.js" />"></script>
|
||||
<script src="<@s.url value="/static/js/jquery-1.12.4.min.js" />"></script>
|
||||
<script src="<@s.url value="/static/js/jquery-ui-1.12.1.min.js" />"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="menu">
|
||||
|
||||
@@ -22,11 +22,11 @@
|
||||
<head>
|
||||
<title>${bundle.symbolicName!}</title>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="<@s.url value="${parameters.staticContentPath}/css/main.css" />" />
|
||||
<link rel="stylesheet" type="text/css" href="<@s.url value="${parameters.staticContentPath}/css/redmond/jquery-ui-1.12.1.redmond.css" />" />
|
||||
<link rel="stylesheet" type="text/css" href="<@s.url value="/static/css/main.css" />" />
|
||||
<link rel="stylesheet" type="text/css" href="<@s.url value="/static/css/redmond/jquery-ui-1.12.1.redmond.css" />" />
|
||||
|
||||
<script src="<@s.url value="${parameters.staticContentPath}/js/jquery-1.12.4.min.js" />"></script>
|
||||
<script src="<@s.url value="${parameters.staticContentPath}/js/jquery-ui-1.12.1.min.js" />"></script>
|
||||
<script src="<@s.url value="/static/js/jquery-1.12.4.min.js" />"></script>
|
||||
<script src="<@s.url value="/static/js/jquery-ui-1.12.1.min.js" />"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
|
||||
@@ -22,11 +22,11 @@
|
||||
<head>
|
||||
<title>OSGi Bundles</title>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="<@s.url value="${parameters.staticContentPath}/css/main.css" />" />
|
||||
<link rel="stylesheet" type="text/css" href="<@s.url value="${parameters.staticContentPath}/css/redmond/jquery-ui-1.12.1.redmond.css" />" />
|
||||
<link rel="stylesheet" type="text/css" href="<@s.url value="/static/css/main.css" />" />
|
||||
<link rel="stylesheet" type="text/css" href="<@s.url value="/static/css/redmond/jquery-ui-1.12.1.redmond.css" />" />
|
||||
|
||||
<script src="<@s.url value="${parameters.staticContentPath}/js/jquery-1.12.4.min.js" />"></script>
|
||||
<script src="<@s.url value="${parameters.staticContentPath}/js/jquery-ui-1.12.1.min.js" />"></script>
|
||||
<script src="<@s.url value="/static/js/jquery-1.12.4.min.js" />"></script>
|
||||
<script src="<@s.url value="/static/js/jquery-ui-1.12.1.min.js" />"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
+13
-7
@@ -24,25 +24,31 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-osgi-bundles</artifactId>
|
||||
<version>6.0.3</version>
|
||||
<version>2.5.26</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-osgi-demo-bundle</artifactId>
|
||||
<packaging>bundle</packaging>
|
||||
<name>DEPRECATED: Struts 2 OSGi Demo Bundle - since 6.0.0</name>
|
||||
<name>Struts 2 OSGi Demo Bundle</name>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.velocity</groupId>
|
||||
<artifactId>velocity</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-velocity-plugin</artifactId>
|
||||
<groupId>org.apache.velocity</groupId>
|
||||
<artifactId>velocity-tools</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-digester</groupId>
|
||||
<artifactId>commons-digester</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-convention-plugin</artifactId>
|
||||
@@ -52,7 +58,7 @@
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-osgi-plugin</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
@@ -64,7 +70,7 @@
|
||||
<configuration>
|
||||
<instructions>
|
||||
<manifestLocation>META-INF</manifestLocation>
|
||||
<Import-Package>*</Import-Package>
|
||||
<Import-Package>*,com.opensymphony.xwork2</Import-Package>
|
||||
<Spring-Context>*;create-asynchronously:=false</Spring-Context>
|
||||
<Struts2-Enabled>true</Struts2-Enabled>
|
||||
</instructions>
|
||||
|
||||
@@ -22,7 +22,7 @@ package actions.osgi;
|
||||
|
||||
import com.opensymphony.xwork2.ActionSupport;
|
||||
import org.apache.struts2.convention.annotation.ResultPath;
|
||||
import org.apache.struts2.osgi.action.BundleContextAware;
|
||||
import org.apache.struts2.osgi.interceptor.BundleContextAware;
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.BundleContext;
|
||||
|
||||
@@ -33,7 +33,7 @@ import org.osgi.framework.BundleContext;
|
||||
public class BundlesAction extends ActionSupport implements BundleContextAware {
|
||||
private BundleContext bundleContext;
|
||||
|
||||
public void withBundleContext(BundleContext bundleContext) {
|
||||
public void setBundleContext(BundleContext bundleContext) {
|
||||
this.bundleContext = bundleContext;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
<constant name="struts.velocity.manager.classname" value="org.apache.struts2.osgi.VelocityBundleResourceLoader" />
|
||||
<constant name="struts.staticContentLoader" value="org.apache.struts2.osgi.loaders.StaticContentBundleResourceLoader" />
|
||||
|
||||
<package name="bundle-demo" namespace="/osgi" extends="osgi-default, velocity-default" strict-method-invocation="true">
|
||||
<package name="bundle-demo" namespace="/osgi" extends="osgi-default" strict-method-invocation="true">
|
||||
|
||||
<default-action-ref name="home" />
|
||||
|
||||
|
||||
+8
-5
@@ -24,12 +24,12 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-parent</artifactId>
|
||||
<version>6.0.3</version>
|
||||
<version>2.5.26</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-osgi-bundles</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<name>DEPRECATED: Struts 2 OSGi Bundles - since 6.0.0</name>
|
||||
<name>Struts OSGi Bundles</name>
|
||||
|
||||
<modules>
|
||||
<module>admin</module>
|
||||
@@ -53,17 +53,20 @@
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<version>2.4</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
<reporting>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.rat</groupId>
|
||||
<artifactId>apache-rat-plugin</artifactId>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>rat-maven-plugin</artifactId>
|
||||
<version>1.0-alpha-2</version>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>pom.xml</include>
|
||||
|
||||
+88
-22
@@ -24,14 +24,14 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-parent</artifactId>
|
||||
<version>6.0.3</version>
|
||||
<version>2.5.26</version>
|
||||
</parent>
|
||||
<artifactId>struts2-core</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Struts 2 Core</name>
|
||||
|
||||
<properties>
|
||||
<tlib.version>6.0</tlib.version>
|
||||
<tlib.version>2.3</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>-Duser.language=en -Duser.region=US</argLine>
|
||||
<properties>
|
||||
<property>
|
||||
<name>maven.testng.output.dir</name>
|
||||
@@ -177,6 +178,26 @@
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>default-tools.jar</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>java.vendor</name>
|
||||
<value>Sun Microsystems Inc.</value>
|
||||
</property>
|
||||
</activation>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.sun</groupId>
|
||||
<artifactId>tools</artifactId>
|
||||
<version>1.7.0</version>
|
||||
<!-- Match version of minimum compatible version -->
|
||||
<scope>system</scope>
|
||||
<systemPath>${java.home}/../lib/tools.jar</systemPath>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
|
||||
</profiles>
|
||||
|
||||
|
||||
@@ -188,12 +209,12 @@
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.servlet.jsp</groupId>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>jsp-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
@@ -203,10 +224,24 @@
|
||||
<artifactId>ognl</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Velocity -->
|
||||
<dependency>
|
||||
<groupId>org.apache.velocity</groupId>
|
||||
<artifactId>velocity</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.velocity</groupId>
|
||||
<artifactId>velocity-tools</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- Logging -->
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-api</artifactId>
|
||||
<version>${log4j2.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- File upload -->
|
||||
@@ -229,28 +264,50 @@
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-text</artifactId>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aop</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aspects</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context-support</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context-support</artifactId>
|
||||
<scope>test</scope>
|
||||
<groupId>cglib</groupId>
|
||||
<artifactId>cglib-nodep</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -304,13 +361,13 @@
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<groupId>org.easytesting</groupId>
|
||||
<artifactId>fest-assert</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -352,6 +409,15 @@
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- The Servlet API mocks in Spring Framework 4.x only supports Servlet 3.0 and higher.
|
||||
This is only necessary in tests-->
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@ import com.opensymphony.xwork2.util.TextParseUtil;
|
||||
import com.opensymphony.xwork2.util.ValueStack;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.StrutsException;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -202,11 +201,7 @@ public class ActionChainResult implements Result {
|
||||
* @param invocation the DefaultActionInvocation calling the action call stack
|
||||
*/
|
||||
public void execute(ActionInvocation invocation) throws Exception {
|
||||
if (invocation == null) {
|
||||
throw new IllegalArgumentException("Invocation cannot be null!");
|
||||
}
|
||||
|
||||
ValueStack stack = invocation.getInvocationContext().getValueStack();
|
||||
ValueStack stack = ActionContext.getContext().getValueStack();
|
||||
String finalNamespace = this.namespace != null
|
||||
? TextParseUtil.translateVariables(namespace, stack)
|
||||
: invocation.getProxy().getNamespace();
|
||||
@@ -217,19 +212,18 @@ public class ActionChainResult implements Result {
|
||||
|
||||
if (isInChainHistory(finalNamespace, finalActionName, finalMethodName)) {
|
||||
addToHistory(finalNamespace, finalActionName, finalMethodName);
|
||||
throw new StrutsException("Infinite recursion detected: " + ActionChainResult.getChainHistory().toString());
|
||||
throw new XWorkException("Infinite recursion detected: " + ActionChainResult.getChainHistory().toString());
|
||||
}
|
||||
|
||||
if (ActionChainResult.getChainHistory().isEmpty() && invocation.getProxy() != null) {
|
||||
if (ActionChainResult.getChainHistory().isEmpty() && invocation != null && invocation.getProxy() != null) {
|
||||
addToHistory(finalNamespace, invocation.getProxy().getActionName(), invocation.getProxy().getMethod());
|
||||
}
|
||||
addToHistory(finalNamespace, finalActionName, finalMethodName);
|
||||
|
||||
Map<String, Object> extraContext = ActionContext.of(new HashMap<>())
|
||||
.withValueStack(invocation.getInvocationContext().getValueStack())
|
||||
.withParameters(invocation.getInvocationContext().getParameters())
|
||||
.with(CHAIN_HISTORY, ActionChainResult.getChainHistory())
|
||||
.getContextMap();
|
||||
HashMap<String, Object> extraContext = new HashMap<>();
|
||||
extraContext.put(ActionContext.VALUE_STACK, ActionContext.getContext().getValueStack());
|
||||
extraContext.put(ActionContext.PARAMETERS, ActionContext.getContext().getParameters());
|
||||
extraContext.put(CHAIN_HISTORY, ActionChainResult.getChainHistory());
|
||||
|
||||
LOG.debug("Chaining to action {}", finalActionName);
|
||||
|
||||
|
||||
@@ -18,18 +18,10 @@
|
||||
*/
|
||||
package com.opensymphony.xwork2;
|
||||
|
||||
import com.opensymphony.xwork2.conversion.impl.ConversionData;
|
||||
import com.opensymphony.xwork2.inject.Container;
|
||||
import com.opensymphony.xwork2.util.ValueStack;
|
||||
import org.apache.struts2.StrutsException;
|
||||
import org.apache.struts2.StrutsStatics;
|
||||
import org.apache.struts2.dispatcher.HttpParameters;
|
||||
import org.apache.struts2.dispatcher.mapper.ActionMapping;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.jsp.PageContext;
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
@@ -62,167 +54,76 @@ public class ActionContext implements Serializable {
|
||||
|
||||
/**
|
||||
* Constant for the name of the action being executed.
|
||||
*
|
||||
* @deprecated scope will be narrowed to "private", use helper methods instead
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String ACTION_NAME = "com.opensymphony.xwork2.ActionContext.name";
|
||||
|
||||
/**
|
||||
* Constant for the {@link com.opensymphony.xwork2.util.ValueStack OGNL value stack}.
|
||||
*
|
||||
* @deprecated scope will be narrowed to "private", use helper methods instead
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String VALUE_STACK = ValueStack.VALUE_STACK;
|
||||
|
||||
/**
|
||||
* Constant for the action's session.
|
||||
*
|
||||
* @deprecated scope will be narrowed to "private", use helper methods instead
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String SESSION = "com.opensymphony.xwork2.ActionContext.session";
|
||||
|
||||
/**
|
||||
* Constant for the action's application context.
|
||||
*
|
||||
* @deprecated scope will be narrowed to "private", use helper methods instead
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String APPLICATION = "com.opensymphony.xwork2.ActionContext.application";
|
||||
|
||||
/**
|
||||
* Constant for the action's parameters.
|
||||
*
|
||||
* @deprecated scope will be narrowed to "private", use helper methods instead
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String PARAMETERS = "com.opensymphony.xwork2.ActionContext.parameters";
|
||||
|
||||
/**
|
||||
* Constant for the action's locale.
|
||||
*
|
||||
* @deprecated scope will be narrowed to "private", use helper methods instead
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String LOCALE = "com.opensymphony.xwork2.ActionContext.locale";
|
||||
|
||||
/**
|
||||
* Constant for the action's {@link com.opensymphony.xwork2.ActionInvocation invocation} context.
|
||||
*
|
||||
* @deprecated scope will be narrowed to "private", use helper methods instead
|
||||
* Constant for the action's type converter.
|
||||
*/
|
||||
public static final String TYPE_CONVERTER = "com.opensymphony.xwork2.ActionContext.typeConverter";
|
||||
|
||||
/**
|
||||
* Constant for the action's {@link com.opensymphony.xwork2.ActionInvocation invocation} context.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String ACTION_INVOCATION = "com.opensymphony.xwork2.ActionContext.actionInvocation";
|
||||
|
||||
/**
|
||||
* Constant for the map of type conversion errors.
|
||||
*
|
||||
* @deprecated scope will be narrowed to "private", use helper methods instead
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String CONVERSION_ERRORS = "com.opensymphony.xwork2.ActionContext.conversionErrors";
|
||||
|
||||
|
||||
/**
|
||||
* Constant for the container
|
||||
*
|
||||
* @deprecated scope will be narrowed to "private", use helper methods instead
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String CONTAINER = "com.opensymphony.xwork2.ActionContext.container";
|
||||
|
||||
private final Map<String, Object> context;
|
||||
|
||||
private Map<String, Object> context;
|
||||
|
||||
/**
|
||||
* Creates a new ActionContext initialized with another context.
|
||||
*
|
||||
* @param context a context map.
|
||||
*/
|
||||
protected ActionContext(Map<String, Object> context) {
|
||||
public ActionContext(Map<String, Object> context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new ActionContext based on passed in Map
|
||||
* and assign this instance to the current thread
|
||||
*
|
||||
* @param context a map with context values
|
||||
* @return new ActionContext
|
||||
*/
|
||||
public static ActionContext of(Map<String, Object> context) {
|
||||
if (context == null) {
|
||||
throw new IllegalArgumentException("Context cannot be null!");
|
||||
}
|
||||
return new ActionContext(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds the provided context with the current thread
|
||||
*
|
||||
* @param actionContext context to bind to the thread
|
||||
* @return context which was bound to the thread
|
||||
*/
|
||||
public static ActionContext bind(ActionContext actionContext) {
|
||||
ActionContext.setContext(actionContext);
|
||||
return ActionContext.getContext();
|
||||
}
|
||||
|
||||
public static boolean containsValueStack(Map<String, Object> context) {
|
||||
return context != null && context.containsKey(VALUE_STACK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds this context with the current thread
|
||||
*
|
||||
* @return this context which was bound to the thread
|
||||
*/
|
||||
public ActionContext bind() {
|
||||
ActionContext.setContext(this);
|
||||
return ActionContext.getContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Wipes out current ActionContext, use wisely!
|
||||
*/
|
||||
public static void clear() {
|
||||
actionContext.remove();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the action context for the current thread.
|
||||
*
|
||||
* @param context the action context.
|
||||
*/
|
||||
private static void setContext(ActionContext context) {
|
||||
actionContext.set(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ActionContext specific to the current thread.
|
||||
*
|
||||
* @return the ActionContext for the current thread, is never <tt>null</tt>.
|
||||
*/
|
||||
public static ActionContext getContext() {
|
||||
return actionContext.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the action invocation (the execution state).
|
||||
*
|
||||
* @param actionInvocation the action execution state.
|
||||
* @deprecated use {@link #withActionInvocation(ActionInvocation)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public void setActionInvocation(ActionInvocation actionInvocation) {
|
||||
put(ACTION_INVOCATION, actionInvocation);
|
||||
}
|
||||
|
||||
public ActionContext withActionInvocation(ActionInvocation actionInvocation) {
|
||||
put(ACTION_INVOCATION, actionInvocation);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the action invocation (the execution state).
|
||||
*
|
||||
@@ -236,28 +137,47 @@ public class ActionContext implements Serializable {
|
||||
* Sets the action's application context.
|
||||
*
|
||||
* @param application the action's application context.
|
||||
* @deprecated use {@link #withApplication(Map)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public void setApplication(Map<String, Object> application) {
|
||||
put(APPLICATION, application);
|
||||
}
|
||||
|
||||
public ActionContext withApplication(Map<String, Object> application) {
|
||||
put(APPLICATION, application);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Map of the ServletContext when in a servlet environment or a generic application level Map otherwise.
|
||||
*
|
||||
* @return a Map of ServletContext or generic application level Map
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Map<String, Object> getApplication() {
|
||||
return (Map<String, Object>) get(APPLICATION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the action context for the current thread.
|
||||
*
|
||||
* @param context the action context.
|
||||
*/
|
||||
public static void setContext(ActionContext context) {
|
||||
actionContext.set(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ActionContext specific to the current thread.
|
||||
*
|
||||
* @return the ActionContext for the current thread, is never <tt>null</tt>.
|
||||
*/
|
||||
public static ActionContext getContext() {
|
||||
return actionContext.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the action's context map.
|
||||
*
|
||||
* @param contextMap the context map.
|
||||
*/
|
||||
public void setContextMap(Map<String, Object> contextMap) {
|
||||
getContext().context = contextMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the context map.
|
||||
*
|
||||
@@ -271,30 +191,23 @@ public class ActionContext implements Serializable {
|
||||
* Sets conversion errors which occurred when executing the action.
|
||||
*
|
||||
* @param conversionErrors a Map of errors which occurred when executing the action.
|
||||
* @deprecated use {@link #withConversionErrors(Map)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public void setConversionErrors(Map<String, ConversionData> conversionErrors) {
|
||||
public void setConversionErrors(Map<String, Object> conversionErrors) {
|
||||
put(CONVERSION_ERRORS, conversionErrors);
|
||||
}
|
||||
|
||||
public ActionContext withConversionErrors(Map<String, ConversionData> conversionErrors) {
|
||||
put(CONVERSION_ERRORS, conversionErrors);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the map of conversion errors which occurred when executing the action.
|
||||
*
|
||||
* @return the map of conversion errors which occurred when executing the action or an empty map if
|
||||
* there were no errors.
|
||||
* there were no errors.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Map<String, ConversionData> getConversionErrors() {
|
||||
Map<String, ConversionData> errors = (Map<String, ConversionData>) get(CONVERSION_ERRORS);
|
||||
public Map<String, Object> getConversionErrors() {
|
||||
Map<String, Object> errors = (Map) get(CONVERSION_ERRORS);
|
||||
|
||||
if (errors == null) {
|
||||
errors = withConversionErrors(new HashMap<>()).getConversionErrors();
|
||||
errors = new HashMap<>();
|
||||
setConversionErrors(errors);
|
||||
}
|
||||
|
||||
return errors;
|
||||
@@ -304,18 +217,11 @@ public class ActionContext implements Serializable {
|
||||
* Sets the Locale for the current action.
|
||||
*
|
||||
* @param locale the Locale for the current action.
|
||||
* @deprecated use {@link #withLocale(Locale)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public void setLocale(Locale locale) {
|
||||
put(LOCALE, locale);
|
||||
}
|
||||
|
||||
public ActionContext withLocale(Locale locale) {
|
||||
put(LOCALE, locale);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Locale of the current action. If no locale was ever specified the platform's
|
||||
* {@link java.util.Locale#getDefault() default locale} is used.
|
||||
@@ -337,18 +243,11 @@ public class ActionContext implements Serializable {
|
||||
* Sets the name of the current Action in the ActionContext.
|
||||
*
|
||||
* @param name the name of the current action.
|
||||
* @deprecated use {@link #withActionName(String)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public void setName(String name) {
|
||||
put(ACTION_NAME, name);
|
||||
}
|
||||
|
||||
public ActionContext withActionName(String actionName) {
|
||||
put(ACTION_NAME, actionName);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the current Action.
|
||||
*
|
||||
@@ -358,15 +257,6 @@ public class ActionContext implements Serializable {
|
||||
return (String) get(ACTION_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the current Action.
|
||||
*
|
||||
* @return the name of the current action.
|
||||
*/
|
||||
public String getActionName() {
|
||||
return (String) get(ACTION_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the action parameters.
|
||||
*
|
||||
@@ -376,17 +266,12 @@ public class ActionContext implements Serializable {
|
||||
put(PARAMETERS, parameters);
|
||||
}
|
||||
|
||||
public ActionContext withParameters(HttpParameters parameters) {
|
||||
put(PARAMETERS, parameters);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Map of the HttpServletRequest parameters when in a servlet environment or a generic Map of
|
||||
* parameters otherwise.
|
||||
*
|
||||
* @return a Map of HttpServletRequest parameters or a multipart map when in a servlet environment, or a
|
||||
* generic Map of parameters otherwise.
|
||||
* generic Map of parameters otherwise.
|
||||
*/
|
||||
public HttpParameters getParameters() {
|
||||
return (HttpParameters) get(PARAMETERS);
|
||||
@@ -395,25 +280,17 @@ public class ActionContext implements Serializable {
|
||||
/**
|
||||
* Sets a map of action session values.
|
||||
*
|
||||
* @param session the session values.
|
||||
* @deprecated use {@link #withSession(Map)} instead
|
||||
* @param session the session values.
|
||||
*/
|
||||
@Deprecated
|
||||
public void setSession(Map<String, Object> session) {
|
||||
put(SESSION, session);
|
||||
}
|
||||
|
||||
public ActionContext withSession(Map<String, Object> session) {
|
||||
put(SESSION, session);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Map of HttpSession values when in a servlet environment or a generic session map otherwise.
|
||||
*
|
||||
* @return the Map of HttpSession values when in a servlet environment or a generic session map otherwise.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Map<String, Object> getSession() {
|
||||
return (Map<String, Object>) get(SESSION);
|
||||
}
|
||||
@@ -422,18 +299,11 @@ public class ActionContext implements Serializable {
|
||||
* Sets the OGNL value stack.
|
||||
*
|
||||
* @param stack the OGNL value stack.
|
||||
* @deprecated Use {@link #withValueStack(ValueStack)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public void setValueStack(ValueStack stack) {
|
||||
put(VALUE_STACK, stack);
|
||||
}
|
||||
|
||||
public ActionContext withValueStack(ValueStack valueStack) {
|
||||
put(VALUE_STACK, valueStack);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the OGNL value stack.
|
||||
*
|
||||
@@ -442,38 +312,31 @@ public class ActionContext implements Serializable {
|
||||
public ValueStack getValueStack() {
|
||||
return (ValueStack) get(VALUE_STACK);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the container for this request
|
||||
*
|
||||
*
|
||||
* @param cont The container
|
||||
* @deprecated use {@link #withContainer(Container)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public void setContainer(Container cont) {
|
||||
put(CONTAINER, cont);
|
||||
}
|
||||
|
||||
public ActionContext withContainer(Container container) {
|
||||
put(CONTAINER, container);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the container for this request
|
||||
*
|
||||
*
|
||||
* @return The container
|
||||
*/
|
||||
public Container getContainer() {
|
||||
return (Container) get(CONTAINER);
|
||||
}
|
||||
|
||||
|
||||
public <T> T getInstance(Class<T> type) {
|
||||
Container cont = getContainer();
|
||||
if (cont != null) {
|
||||
return cont.getInstance(type);
|
||||
} else {
|
||||
throw new StrutsException("Cannot find an initialized container for this request.");
|
||||
throw new XWorkException("Cannot find an initialized container for this request.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -496,129 +359,4 @@ public class ActionContext implements Serializable {
|
||||
public void put(String key, Object value) {
|
||||
context.put(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets ServletContext associated with current action
|
||||
*
|
||||
* @return current ServletContext
|
||||
*/
|
||||
public ServletContext getServletContext() {
|
||||
return (ServletContext) get(StrutsStatics.SERVLET_CONTEXT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns ServletContext to action context
|
||||
*
|
||||
* @param servletContext associated with current request
|
||||
* @return ActionContext
|
||||
*/
|
||||
public ActionContext withServletContext(ServletContext servletContext) {
|
||||
put(StrutsStatics.SERVLET_CONTEXT, servletContext);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets ServletRequest associated with current action
|
||||
*
|
||||
* @return current ServletRequest
|
||||
*/
|
||||
public HttpServletRequest getServletRequest() {
|
||||
return (HttpServletRequest) get(StrutsStatics.HTTP_REQUEST);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns ServletRequest to action context
|
||||
*
|
||||
* @param request associated with current request
|
||||
* @return ActionContext
|
||||
*/
|
||||
public ActionContext withServletRequest(HttpServletRequest request) {
|
||||
put(StrutsStatics.HTTP_REQUEST, request);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets ServletResponse associated with current action
|
||||
*
|
||||
* @return current ServletResponse
|
||||
*/
|
||||
public HttpServletResponse getServletResponse() {
|
||||
return (HttpServletResponse) get(StrutsStatics.HTTP_RESPONSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns ServletResponse to action context
|
||||
*
|
||||
* @param response associated with current request
|
||||
* @return ActionContext
|
||||
*/
|
||||
public ActionContext withServletResponse(HttpServletResponse response) {
|
||||
put(StrutsStatics.HTTP_RESPONSE, response);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets PageContext associated with current action
|
||||
*
|
||||
* @return current PageContext
|
||||
*/
|
||||
public PageContext getPageContext() {
|
||||
return (PageContext) get(StrutsStatics.PAGE_CONTEXT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns PageContext to action context
|
||||
*
|
||||
* @param pageContext associated with current request
|
||||
* @return ActionContext
|
||||
*/
|
||||
public ActionContext withPageContext(PageContext pageContext) {
|
||||
put(StrutsStatics.PAGE_CONTEXT, pageContext);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets ActionMapping associated with current action
|
||||
*
|
||||
* @return current ActionMapping
|
||||
*/
|
||||
public ActionMapping getActionMapping() {
|
||||
return (ActionMapping) get(StrutsStatics.ACTION_MAPPING);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns ActionMapping to action context
|
||||
*
|
||||
* @param actionMapping associated with current request
|
||||
* @return ActionContext
|
||||
*/
|
||||
public ActionContext withActionMapping(ActionMapping actionMapping) {
|
||||
put(StrutsStatics.ACTION_MAPPING, actionMapping);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns an extra context map to action context
|
||||
*
|
||||
* @param extraContext to add to the current action context
|
||||
* @return ActionContext
|
||||
*/
|
||||
public ActionContext withExtraContext(Map<String, Object> extraContext) {
|
||||
if (extraContext != null) {
|
||||
context.putAll(extraContext);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds arbitrary key to action context
|
||||
*
|
||||
* @param key a string
|
||||
* @param value an object
|
||||
* @return ActionContext
|
||||
*/
|
||||
public ActionContext with(String key, Object value) {
|
||||
put(key, value);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
*/
|
||||
package com.opensymphony.xwork2;
|
||||
|
||||
import com.opensymphony.xwork2.conversion.impl.ConversionData;
|
||||
import com.opensymphony.xwork2.inject.Container;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import com.opensymphony.xwork2.interceptor.ValidationAware;
|
||||
@@ -45,32 +44,26 @@ public class ActionSupport implements Action, Validateable, ValidationAware, Tex
|
||||
|
||||
protected Container container;
|
||||
|
||||
@Override
|
||||
public void setActionErrors(Collection<String> errorMessages) {
|
||||
validationAware.setActionErrors(errorMessages);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getActionErrors() {
|
||||
return validationAware.getActionErrors();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActionMessages(Collection<String> messages) {
|
||||
validationAware.setActionMessages(messages);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getActionMessages() {
|
||||
return validationAware.getActionMessages();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFieldErrors(Map<String, List<String>> errorMap) {
|
||||
validationAware.setFieldErrors(errorMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, List<String>> getFieldErrors() {
|
||||
return validationAware.getFieldErrors();
|
||||
}
|
||||
@@ -90,52 +83,42 @@ public class ActionSupport implements Action, Validateable, ValidationAware, Tex
|
||||
return getLocaleProvider().isValidLocale(locale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasKey(String key) {
|
||||
return getTextProvider().hasKey(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(String aTextName) {
|
||||
return getTextProvider().getText(aTextName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(String aTextName, String defaultValue) {
|
||||
return getTextProvider().getText(aTextName, defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(String aTextName, String defaultValue, String obj) {
|
||||
return getTextProvider().getText(aTextName, defaultValue, obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(String aTextName, List<?> args) {
|
||||
return getTextProvider().getText(aTextName, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(String key, String[] args) {
|
||||
return getTextProvider().getText(key, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(String aTextName, String defaultValue, List<?> args) {
|
||||
return getTextProvider().getText(aTextName, defaultValue, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(String key, String defaultValue, String[] args) {
|
||||
return getTextProvider().getText(key, defaultValue, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(String key, String defaultValue, List<?> args, ValueStack stack) {
|
||||
return getTextProvider().getText(key, defaultValue, args, stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(String key, String defaultValue, String[] args, ValueStack stack) {
|
||||
return getTextProvider().getText(key, defaultValue, args, stack);
|
||||
}
|
||||
@@ -148,9 +131,9 @@ public class ActionSupport implements Action, Validateable, ValidationAware, Tex
|
||||
* @return formatted expr with format specified by key
|
||||
*/
|
||||
public String getFormatted(String key, String expr) {
|
||||
Map<String, ConversionData> conversionErrors = ActionContext.getContext().getConversionErrors();
|
||||
Map<String, Object> conversionErrors = ActionContext.getContext().getConversionErrors();
|
||||
if (conversionErrors.containsKey(expr)) {
|
||||
String[] vals = (String[]) conversionErrors.get(expr).getValue();
|
||||
String[] vals = (String[]) conversionErrors.get(expr);
|
||||
return vals[0];
|
||||
} else {
|
||||
final ValueStack valueStack = ActionContext.getContext().getValueStack();
|
||||
@@ -159,27 +142,22 @@ public class ActionSupport implements Action, Validateable, ValidationAware, Tex
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceBundle getTexts() {
|
||||
return getTextProvider().getTexts();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceBundle getTexts(String aBundleName) {
|
||||
return getTextProvider().getTexts(aBundleName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addActionError(String anErrorMessage) {
|
||||
validationAware.addActionError(anErrorMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addActionMessage(String aMessage) {
|
||||
validationAware.addActionMessage(aMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFieldError(String fieldName, String errorMessage) {
|
||||
validationAware.addFieldError(fieldName, errorMessage);
|
||||
}
|
||||
@@ -202,27 +180,22 @@ public class ActionSupport implements Action, Validateable, ValidationAware, Tex
|
||||
* @return returns {@link #SUCCESS}
|
||||
* @throws Exception can be thrown by subclasses.
|
||||
*/
|
||||
@Override
|
||||
public String execute() throws Exception {
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasActionErrors() {
|
||||
return validationAware.hasActionErrors();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasActionMessages() {
|
||||
return validationAware.hasActionMessages();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasErrors() {
|
||||
return validationAware.hasErrors();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasFieldErrors() {
|
||||
return validationAware.hasFieldErrors();
|
||||
}
|
||||
@@ -271,9 +244,7 @@ public class ActionSupport implements Action, Validateable, ValidationAware, Tex
|
||||
* A default implementation that validates nothing.
|
||||
* Subclasses should override this method to provide validations.
|
||||
*/
|
||||
@Override
|
||||
public void validate() {
|
||||
// A default implementation that validates nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -312,7 +283,8 @@ public class ActionSupport implements Action, Validateable, ValidationAware, Tex
|
||||
*/
|
||||
protected TextProvider getTextProvider() {
|
||||
if (textProvider == null) {
|
||||
final TextProviderFactory tpf = getContainer().getInstance(TextProviderFactory.class);
|
||||
Container container = getContainer();
|
||||
TextProviderFactory tpf = container.getInstance(TextProviderFactory.class);
|
||||
textProvider = tpf.createInstance(getClass());
|
||||
}
|
||||
return textProvider;
|
||||
@@ -320,7 +292,8 @@ public class ActionSupport implements Action, Validateable, ValidationAware, Tex
|
||||
|
||||
protected LocaleProvider getLocaleProvider() {
|
||||
if (localeProvider == null) {
|
||||
final LocaleProviderFactory localeProviderFactory = getContainer().getInstance(LocaleProviderFactory.class);
|
||||
Container container = getContainer();
|
||||
LocaleProviderFactory localeProviderFactory = container.getInstance(LocaleProviderFactory.class);
|
||||
localeProvider = localeProviderFactory.createLocaleProvider();
|
||||
}
|
||||
return localeProvider;
|
||||
|
||||
@@ -30,17 +30,16 @@ import com.opensymphony.xwork2.interceptor.WithLazyParams;
|
||||
import com.opensymphony.xwork2.ognl.OgnlUtil;
|
||||
import com.opensymphony.xwork2.util.ValueStack;
|
||||
import com.opensymphony.xwork2.util.ValueStackFactory;
|
||||
import com.opensymphony.xwork2.util.profiling.UtilTimerStack;
|
||||
import ognl.MethodFailedException;
|
||||
import ognl.NoSuchPropertyException;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.StrutsException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
/**
|
||||
* The Default ActionInvocation implementation
|
||||
@@ -65,15 +64,13 @@ public class DefaultActionInvocation implements ActionInvocation {
|
||||
protected Result explicitResult;
|
||||
protected String resultCode;
|
||||
protected boolean executed = false;
|
||||
protected boolean pushAction;
|
||||
protected boolean pushAction = true;
|
||||
protected ObjectFactory objectFactory;
|
||||
protected ActionEventListener actionEventListener;
|
||||
protected ValueStackFactory valueStackFactory;
|
||||
protected Container container;
|
||||
protected UnknownHandlerManager unknownHandlerManager;
|
||||
protected OgnlUtil ognlUtil;
|
||||
protected AsyncManager asyncManager;
|
||||
protected Callable asyncAction;
|
||||
protected WithLazyParams.LazyParamInjector lazyParamInjector;
|
||||
|
||||
public DefaultActionInvocation(final Map<String, Object> extraContext, final boolean pushAction) {
|
||||
@@ -111,11 +108,6 @@ public class DefaultActionInvocation implements ActionInvocation {
|
||||
this.ognlUtil = ognlUtil;
|
||||
}
|
||||
|
||||
@Inject(required=false)
|
||||
public void setAsyncManager(AsyncManager asyncManager) {
|
||||
this.asyncManager = asyncManager;
|
||||
}
|
||||
|
||||
public Object getAction() {
|
||||
return action;
|
||||
}
|
||||
@@ -225,7 +217,7 @@ public class DefaultActionInvocation implements ActionInvocation {
|
||||
return objectFactory.buildResult(resultConfig, invocationContext.getContextMap());
|
||||
} catch (Exception e) {
|
||||
LOG.error("There was an exception while instantiating the result of type {}", resultConfig.getClassName(), e);
|
||||
throw new StrutsException(e, resultConfig);
|
||||
throw new XWorkException(e, resultConfig);
|
||||
}
|
||||
} else if (resultCode != null && !Action.NONE.equals(resultCode) && unknownHandlerManager.hasUnknownHandlers()) {
|
||||
return unknownHandlerManager.handleUnknownResult(invocationContext, proxy.getActionName(), proxy.getConfig(), resultCode);
|
||||
@@ -237,31 +229,31 @@ public class DefaultActionInvocation implements ActionInvocation {
|
||||
* @throws ConfigurationException If no result can be found with the returned code
|
||||
*/
|
||||
public String invoke() throws Exception {
|
||||
if (executed) {
|
||||
throw new IllegalStateException("Action has already executed");
|
||||
}
|
||||
String profileKey = "invoke: ";
|
||||
try {
|
||||
UtilTimerStack.push(profileKey);
|
||||
|
||||
if (executed) {
|
||||
throw new IllegalStateException("Action has already executed");
|
||||
}
|
||||
|
||||
if (asyncManager == null || !asyncManager.hasAsyncActionResult()) {
|
||||
if (interceptors.hasNext()) {
|
||||
final InterceptorMapping interceptorMapping = interceptors.next();
|
||||
Interceptor interceptor = interceptorMapping.getInterceptor();
|
||||
if (interceptor instanceof WithLazyParams) {
|
||||
interceptor = lazyParamInjector.injectParams(interceptor, interceptorMapping.getParams(), invocationContext);
|
||||
String interceptorMsg = "interceptorMapping: " + interceptorMapping.getName();
|
||||
UtilTimerStack.push(interceptorMsg);
|
||||
try {
|
||||
Interceptor interceptor = interceptorMapping.getInterceptor();
|
||||
if (interceptor instanceof WithLazyParams) {
|
||||
interceptor = lazyParamInjector.injectParams(interceptor, interceptorMapping.getParams(), invocationContext);
|
||||
}
|
||||
resultCode = interceptor.intercept(DefaultActionInvocation.this);
|
||||
} finally {
|
||||
UtilTimerStack.pop(interceptorMsg);
|
||||
}
|
||||
resultCode = interceptor.intercept(DefaultActionInvocation.this);
|
||||
} else {
|
||||
resultCode = invokeActionOnly();
|
||||
}
|
||||
} else {
|
||||
Object asyncActionResult = asyncManager.getAsyncActionResult();
|
||||
if (asyncActionResult instanceof Throwable) {
|
||||
throw new Exception((Throwable) asyncActionResult);
|
||||
}
|
||||
asyncAction = null;
|
||||
resultCode = saveResult(proxy.getConfig(), asyncActionResult);
|
||||
}
|
||||
|
||||
if (asyncManager == null || asyncAction == null) {
|
||||
// this is needed because the result will be executed, then control will return to the Interceptor, which will
|
||||
// return above and flow through again
|
||||
if (!executed) {
|
||||
@@ -271,7 +263,14 @@ public class DefaultActionInvocation implements ActionInvocation {
|
||||
for (Object preResultListener : preResultListeners) {
|
||||
PreResultListener listener = (PreResultListener) preResultListener;
|
||||
|
||||
listener.beforeResult(this, resultCode);
|
||||
String _profileKey = "preResultListener: ";
|
||||
try {
|
||||
UtilTimerStack.push(_profileKey);
|
||||
listener.beforeResult(this, resultCode);
|
||||
}
|
||||
finally {
|
||||
UtilTimerStack.pop(_profileKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -282,11 +281,12 @@ public class DefaultActionInvocation implements ActionInvocation {
|
||||
|
||||
executed = true;
|
||||
}
|
||||
} else {
|
||||
asyncManager.invokeAsyncAction(asyncAction);
|
||||
}
|
||||
|
||||
return resultCode;
|
||||
return resultCode;
|
||||
}
|
||||
finally {
|
||||
UtilTimerStack.pop(profileKey);
|
||||
}
|
||||
}
|
||||
|
||||
public String invokeActionOnly() throws Exception {
|
||||
@@ -295,12 +295,14 @@ public class DefaultActionInvocation implements ActionInvocation {
|
||||
|
||||
protected void createAction(Map<String, Object> contextMap) {
|
||||
// load action
|
||||
String timerKey = "actionCreate: " + proxy.getActionName();
|
||||
try {
|
||||
UtilTimerStack.push(timerKey);
|
||||
action = objectFactory.buildAction(proxy.getActionName(), proxy.getNamespace(), proxy.getConfig(), contextMap);
|
||||
} catch (InstantiationException e) {
|
||||
throw new StrutsException("Unable to instantiate Action!", e, proxy.getConfig());
|
||||
throw new XWorkException("Unable to instantiate Action!", e, proxy.getConfig());
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new StrutsException("Illegal access to constructor, is it public?", e, proxy.getConfig());
|
||||
throw new XWorkException("Illegal access to constructor, is it public?", e, proxy.getConfig());
|
||||
} catch (Exception e) {
|
||||
String gripe;
|
||||
|
||||
@@ -315,7 +317,9 @@ public class DefaultActionInvocation implements ActionInvocation {
|
||||
}
|
||||
|
||||
gripe += (((" -- " + e.getMessage()) != null) ? e.getMessage() : " [no message in exception]");
|
||||
throw new StrutsException(gripe, e, proxy.getConfig());
|
||||
throw new XWorkException(gripe, e, proxy.getConfig());
|
||||
} finally {
|
||||
UtilTimerStack.pop(timerKey);
|
||||
}
|
||||
|
||||
if (actionEventListener != null) {
|
||||
@@ -324,31 +328,36 @@ public class DefaultActionInvocation implements ActionInvocation {
|
||||
}
|
||||
|
||||
protected Map<String, Object> createContextMap() {
|
||||
ActionContext actionContext;
|
||||
Map<String, Object> contextMap;
|
||||
|
||||
if (ActionContext.containsValueStack(extraContext)) {
|
||||
if ((extraContext != null) && (extraContext.containsKey(ActionContext.VALUE_STACK))) {
|
||||
// In case the ValueStack was passed in
|
||||
stack = ActionContext.of(extraContext).getValueStack();
|
||||
stack = (ValueStack) extraContext.get(ActionContext.VALUE_STACK);
|
||||
|
||||
if (stack == null) {
|
||||
throw new IllegalStateException("There was a null Stack set into the extra params.");
|
||||
}
|
||||
|
||||
actionContext = stack.getActionContext();
|
||||
contextMap = stack.getContext();
|
||||
} else {
|
||||
// create the value stack
|
||||
// this also adds the ValueStack to its context
|
||||
stack = valueStackFactory.createValueStack();
|
||||
|
||||
// create the action context
|
||||
actionContext = stack.getActionContext();
|
||||
contextMap = stack.getContext();
|
||||
}
|
||||
|
||||
return actionContext
|
||||
.withExtraContext(extraContext)
|
||||
.withActionInvocation(this)
|
||||
.withContainer(container)
|
||||
.getContextMap();
|
||||
// put extraContext in
|
||||
if (extraContext != null) {
|
||||
contextMap.putAll(extraContext);
|
||||
}
|
||||
|
||||
//put this DefaultActionInvocation into the context map
|
||||
contextMap.put(ActionContext.ACTION_INVOCATION, this);
|
||||
contextMap.put(ActionContext.CONTAINER, container);
|
||||
|
||||
return contextMap;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -359,15 +368,21 @@ public class DefaultActionInvocation implements ActionInvocation {
|
||||
private void executeResult() throws Exception {
|
||||
result = createResult();
|
||||
|
||||
if (result != null) {
|
||||
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());
|
||||
} else {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("No result returned for action {} at {}", getAction().getClass().getName(), proxy.getConfig().getLocation());
|
||||
String timerKey = "executeResult: " + getResultCode();
|
||||
try {
|
||||
UtilTimerStack.push(timerKey);
|
||||
if (result != null) {
|
||||
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());
|
||||
} else {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("No result returned for action {} at {}", getAction().getClass().getName(), proxy.getConfig().getLocation());
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
UtilTimerStack.pop(timerKey);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -380,7 +395,7 @@ public class DefaultActionInvocation implements ActionInvocation {
|
||||
ActionContext actionContext = ActionContext.getContext();
|
||||
|
||||
if (actionContext != null) {
|
||||
actionContext.withActionInvocation(this);
|
||||
actionContext.setActionInvocation(this);
|
||||
}
|
||||
|
||||
createAction(contextMap);
|
||||
@@ -390,8 +405,8 @@ public class DefaultActionInvocation implements ActionInvocation {
|
||||
contextMap.put("action", action);
|
||||
}
|
||||
|
||||
invocationContext = ActionContext.of(contextMap)
|
||||
.withActionName(proxy.getActionName());
|
||||
invocationContext = new ActionContext(contextMap);
|
||||
invocationContext.setName(proxy.getActionName());
|
||||
|
||||
createInterceptors(proxy);
|
||||
|
||||
@@ -414,7 +429,10 @@ public class DefaultActionInvocation implements ActionInvocation {
|
||||
|
||||
LOG.debug("Executing action method = {}", methodName);
|
||||
|
||||
String timerKey = "invokeAction: " + proxy.getActionName();
|
||||
try {
|
||||
UtilTimerStack.push(timerKey);
|
||||
|
||||
Object methodResult;
|
||||
try {
|
||||
methodResult = ognlUtil.callMethod(methodName + "()", getStack().getContext(), action);
|
||||
@@ -459,6 +477,8 @@ public class DefaultActionInvocation implements ActionInvocation {
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
} finally {
|
||||
UtilTimerStack.pop(timerKey);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -475,9 +495,6 @@ public class DefaultActionInvocation implements ActionInvocation {
|
||||
// Wire the result automatically
|
||||
container.inject(explicitResult);
|
||||
return null;
|
||||
} else if (methodResult instanceof Callable) {
|
||||
asyncAction = (Callable) methodResult;
|
||||
return null;
|
||||
} else {
|
||||
return (String) methodResult;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,8 @@ import com.opensymphony.xwork2.config.Configuration;
|
||||
import com.opensymphony.xwork2.config.ConfigurationException;
|
||||
import com.opensymphony.xwork2.config.entities.ActionConfig;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import org.apache.commons.text.StringEscapeUtils;
|
||||
import com.opensymphony.xwork2.util.profiling.UtilTimerStack;
|
||||
import org.apache.commons.lang3.StringEscapeUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
@@ -145,15 +146,23 @@ public class DefaultActionProxy implements ActionProxy, Serializable {
|
||||
|
||||
public String execute() throws Exception {
|
||||
ActionContext nestedContext = ActionContext.getContext();
|
||||
ActionContext.bind(invocation.getInvocationContext());
|
||||
ActionContext.setContext(invocation.getInvocationContext());
|
||||
|
||||
String retCode = null;
|
||||
|
||||
String profileKey = "execute: ";
|
||||
try {
|
||||
return invocation.invoke();
|
||||
UtilTimerStack.push(profileKey);
|
||||
|
||||
retCode = invocation.invoke();
|
||||
} finally {
|
||||
if (cleanupContext) {
|
||||
ActionContext.bind(nestedContext);
|
||||
ActionContext.setContext(nestedContext);
|
||||
}
|
||||
UtilTimerStack.pop(profileKey);
|
||||
}
|
||||
|
||||
return retCode;
|
||||
}
|
||||
|
||||
|
||||
@@ -174,21 +183,27 @@ public class DefaultActionProxy implements ActionProxy, Serializable {
|
||||
}
|
||||
|
||||
protected void prepare() {
|
||||
config = configuration.getRuntimeConfiguration().getActionConfig(namespace, actionName);
|
||||
String profileKey = "create DefaultActionProxy: ";
|
||||
try {
|
||||
UtilTimerStack.push(profileKey);
|
||||
config = configuration.getRuntimeConfiguration().getActionConfig(namespace, actionName);
|
||||
|
||||
if (config == null && unknownHandlerManager.hasUnknownHandlers()) {
|
||||
config = unknownHandlerManager.handleUnknownAction(namespace, actionName);
|
||||
}
|
||||
if (config == null) {
|
||||
throw new ConfigurationException(getErrorMessage());
|
||||
}
|
||||
if (config == null && unknownHandlerManager.hasUnknownHandlers()) {
|
||||
config = unknownHandlerManager.handleUnknownAction(namespace, actionName);
|
||||
}
|
||||
if (config == null) {
|
||||
throw new ConfigurationException(getErrorMessage());
|
||||
}
|
||||
|
||||
resolveMethod();
|
||||
resolveMethod();
|
||||
|
||||
if (config.isAllowedMethod(method)) {
|
||||
invocation.init(this);
|
||||
} else {
|
||||
throw new ConfigurationException(prepareNotAllowedErrorMessage());
|
||||
if (config.isAllowedMethod(method)) {
|
||||
invocation.init(this);
|
||||
} else {
|
||||
throw new ConfigurationException(prepareNotAllowedErrorMessage());
|
||||
}
|
||||
} finally {
|
||||
UtilTimerStack.pop(profileKey);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+15
-10
@@ -18,18 +18,23 @@
|
||||
*/
|
||||
package com.opensymphony.xwork2;
|
||||
|
||||
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.
|
||||
* <code>InvalidMetadataException</code>
|
||||
*
|
||||
* @since 6.0.0
|
||||
* @author Rainer Hermanns
|
||||
* @version $Id$
|
||||
*
|
||||
* @deprecated to be removed
|
||||
*/
|
||||
public interface AsyncManager {
|
||||
boolean hasAsyncActionResult();
|
||||
@Deprecated
|
||||
public class InvalidMetadataException extends RuntimeException {
|
||||
|
||||
Object getAsyncActionResult();
|
||||
|
||||
void invokeAsyncAction(Callable asyncAction);
|
||||
/**
|
||||
* Create a new <code>InvalidMetadataException</code> with the supplied error message.
|
||||
*
|
||||
* @param msg the error message
|
||||
*/
|
||||
public InvalidMetadataException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
@@ -31,7 +31,6 @@ import com.opensymphony.xwork2.util.ClassLoaderUtil;
|
||||
import com.opensymphony.xwork2.validator.Validator;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
@@ -69,7 +68,7 @@ public class ObjectFactory implements Serializable {
|
||||
this.container = container;
|
||||
}
|
||||
|
||||
@Inject(value=StrutsConstants.STRUTS_OBJECT_FACTORY_CLASSLOADER, required=false)
|
||||
@Inject(value="objectFactory.classloader", required=false)
|
||||
public void setClassLoader(ClassLoader cl) {
|
||||
this.ccl = cl;
|
||||
}
|
||||
@@ -152,7 +151,7 @@ public class ObjectFactory implements Serializable {
|
||||
* @throws Exception in case of any error
|
||||
*/
|
||||
public Object buildBean(Class clazz, Map<String, Object> extraContext) throws Exception {
|
||||
return container.inject(clazz);
|
||||
return clazz.newInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -161,7 +160,6 @@ public class ObjectFactory implements Serializable {
|
||||
*/
|
||||
protected Object injectInternalBeans(Object obj) {
|
||||
if (obj != null && container != null) {
|
||||
LOG.debug("Injecting internal beans into [{}]", obj.getClass().getSimpleName());
|
||||
container.inject(obj);
|
||||
}
|
||||
return obj;
|
||||
@@ -190,7 +188,11 @@ public class ObjectFactory implements Serializable {
|
||||
*/
|
||||
public Object buildBean(String className, Map<String, Object> extraContext, boolean injectInternal) throws Exception {
|
||||
Class clazz = getClassInstance(className);
|
||||
return buildBean(clazz, extraContext);
|
||||
Object obj = buildBean(clazz, extraContext);
|
||||
if (injectInternal) {
|
||||
injectInternalBeans(obj);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -45,6 +45,6 @@ public interface Result extends Serializable {
|
||||
* @param invocation the invocation context.
|
||||
* @throws Exception can be thrown.
|
||||
*/
|
||||
void execute(ActionInvocation invocation) throws Exception;
|
||||
public void execute(ActionInvocation invocation) throws Exception;
|
||||
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user