Compare commits

...

64 Commits

Author SHA1 Message Date
Lukasz Lenart 4456620b51 [maven-release-plugin] prepare release STRUTS_2_5_19 2018-12-30 15:23:53 +01:00
Yasser Zamani f4a8f42ca4 Merge pull request #304 from lukaszlenart/WW-4975-struts25x
[WW-4975] Upgrades commons-fileupload to version 1.4 - Struts 2.5.x
2018-12-29 20:20:12 +03:30
Lukasz Lenart a6f8895c90 WW-4975 Upgrades commons-fileupload to version 1.4 2018-12-29 17:11:45 +01:00
Aleksandr Mashchenko 46dbdbe018 Add generated tag html 2018-12-21 21:30:31 +02:00
JCgH4164838Gh792C124B5 6f176cc5a7 Enhancement for s:set tag for 2.5.x to allow better tag body whitespace control. (#296)
WW-4995 Add trimBody attribute to set tag
2018-12-20 17:59:30 +02:00
JCgH4164838Gh792C124B5 db085dbeef Updates and cleanup for some configuration-related items (2.5.x). (#291)
* Updates and cleanup for some configuration-related items.
- Made several attributes final.
- Added limiter logic to the setting of certain configuration elements, and increased logging around them.
- Updated unit tests impacted by the limiter logic, including minor typo fixes and locale consistency.
- Minor cleanup while making the changes.

* Update core/src/main/java/com/opensymphony/xwork2/ognl/OgnlValueStackFactory.java

Whitespace cleanup

Co-Authored-By: JCgH4164838Gh792C124B5 <43964333+JCgH4164838Gh792C124B5@users.noreply.github.com>

* Updates and cleanup for some configuration-related items (1st revision).
- Reworked this PR, taking into account feedback and suggestions.
- Removed the if LOG.isxxxEnabled level checks that were added.
- Removed the limiter logic and instead reduced access level of most of the injectable methods to protected.
- Updated the previous unit test changes following removal of limiter logic.

* Minor correction to two debug log statements (as requested by reviewer).

* Update debug messages for pattern checkers, as requested by reviewers.
Avoids confusing users when replacing an empty exclusion set (which improves safety).
Still provides a (slightly milder) message when replacing an empty accepted set (which can reduce safety).
2018-12-20 15:25:34 +03:30
Lukasz Lenart c3205888b4 Merge pull request #293 from JCgH4164838Gh792C124B5/local_25x_LibUpd
Update Struts 2.5.19 to use latest OGNL 3.1.x release available.
2018-12-17 15:42:52 +01:00
JCgH4164838Gh792C124B5 ce9789c4c9 Update Struts 2.5.19 to use latest OGNL 3.1.x release available. 2018-12-13 23:52:29 -05:00
Aleksandr Mashchenko b431755332 Improve optgroup list attributes test
(cherry picked from commit 48d40ae6ac)
2018-12-13 22:42:53 +02:00
Aleksandr Mashchenko c694c6fdfb Improve optgroup template
(cherry picked from commit 60dfc4d141)
2018-12-13 22:42:52 +02:00
Aleksandr Mashchenko 1d49a06272 Add listTitle to optgroup tag
(cherry picked from commit 123a0906ce)
2018-12-13 22:42:52 +02:00
Aleksandr Mashchenko 264e03b7ed Add listCssStyle to optgroup tag
(cherry picked from commit 3c24bae87f)
2018-12-13 22:42:51 +02:00
Aleksandr Mashchenko 2f99110189 WW-4987 Add test for listCssClass in optgroup tag
(cherry picked from commit 94210a02e7)
2018-12-13 22:42:51 +02:00
Aleksandr Mashchenko d33930f3bd WW-4987 Add listCssClass to optgroup tag 2018-12-13 22:42:11 +02:00
Sebastian Peters 360927931c Enhance after_success for Travis CI
Use default bash if-then-else block with semicolon after each command
and fix spelling for "incompatibility".

Don't do `mvn clean` b/c we need the test results for the following
tasks and don't need to rebuild everything.

(cherry picked from commit 352f509)
2018-11-22 14:26:21 +03:30
Lukasz Lenart bff033e6a3 Merge pull request #281 from JCgH4164838Gh792C124B5/localS2_2_5_x_Branch
Minor update to Struts 2.5.x SecurityMemberAccess.
2018-11-22 08:31:34 +01:00
JCgH4164838Gh792C124B5 536d2db4b8 Minor update to Struts 2.5.x SecurityMemberAccess.
Code changes:
- updated SecurityMemberAccess for compatibility with future OGNL 3.1.19+ versions
- updated SecurityMemberAccess constructor (minor cleanup and added comment)
2018-11-21 23:45:13 -05:00
Yasser Zamani 32c8f6f811 [WW-4981] Adds support for JDK11 (#270) 2018-11-19 14:27:21 +03:30
Yasser Zamani 06e5dfc2ab delete not-supported picked from master system property test 2018-11-18 16:30:54 +03:30
Sebastian Peters fe630db5f2 Refactor environment dependant tests
* use org.apache.commons.lang3.SystemUtils for env detection
* use assertThat for more concise assertions
* move setup code to setUp
* some formatting

(cherry picked from commit 8d341df)
2018-11-18 16:01:44 +03:30
Lukasz Lenart b75c0ba5e1 WW-4866 Includes 9+ JDKs
(cherry picked from commit af3ee07)
2018-11-18 15:57:03 +03:30
Lukasz Lenart 8ab102209f WW-4866 Includes 1.8+ JDKs
(cherry picked from commit 2d86cc6)
2018-11-18 15:56:54 +03:30
ORDTesters d7a7c909ea [WW-4977] Fixing flaky test in Jsr168DispatcherTest and Jsr286DispatcherTest.
(cherry picked from commit 2d4e26f)
2018-11-18 15:39:41 +03:30
Yasser Zamani 24e151143e Merge pull request #271 from JCgH4164838Gh792C124B5/localS2_2_5_x_Branch
Back-port enhancement/fix to 2.5.19 unit tests (permits build on Windows)
2018-11-18 12:55:48 +03:30
JCgH4164838Gh792C124B5 c5272d2a0d Backport enhancement/fix from 2.6 to 2.5.19 unit tests to allow Struts 2.5.x build to complete sucessfully on Windows.
- Involves changes to: EnvsValueSubstitutorTest, XmlConfigurationProviderEnvsSubstitutionTest, xwork-test-envs-substitution.xml.
- Note: 2.5.x EnvValueSubstitutor doesn't support system properties (only env properties) so some tests were not backported.
2018-11-17 13:21:20 -05:00
Yasser Zamani 11de8810e4 satisfy coveralls via testing with a not URLClassLoader
See also WW-4845

(cherry picked from commit 02abab3)
2018-11-16 17:30:27 +03:30
Yasser Zamani 75dc4c00d2 pass all current tests with java 9
See also WW-4845

(cherry picked from commit a5d888a)
2018-11-16 17:29:37 +03:30
Lukasz Lenart 415ce3e165 Merge pull request #264 from JCgH4164838Gh792C124B5/localS2_2_5_x_Branch
Update Struts 2.5.19 build with some newer (compatible) library versions
2018-11-14 20:54:19 +01:00
JCgH4164838Gh792C124B5 fe6257b995 Merge branch 'localS2_2_5_x_Branch' of https://github.com/JCgH4164838Gh792C124B5/struts into localS2_2_5_x_Branch
# Conflicts:
#	pom.xml
2018-11-12 15:13:18 -05:00
JCgH4164838Gh792C124B5 3b81a9edaa Update Struts 2.5.19 build with some newer (compatible) library versions.
- Fix SCM tag entry typo in main pom.xml.
- Enhance main pom.xml maven-surefire-plugin configuration to avoid some test-ng related duplication failures:  "Cannot find JUnit method class junit.framework.TestSuite$1.warning".
- Remove unnecessary plugins/embeddedjsp/pom.xml (struts2-embeddedjsp-plugin) maven-surefire-plugin version override (noted with preceding change).
- Update Struts 2.5.19 build to use some newer (compatible) library versions.
  Change the main pom.xml library versions for the following:
  - spring.platformVersion 4.3.13.RELEASE -> 4.3.20.RELEASE
  - ognl 3.1.15 -> 3.1.18  (Note: newest version that passes unit tests)
  - oval 1.31 -> 1.90      (Note: required unit test fix for OValValidationInterceptorTest.java)
  - tiles 3.0.7 -> 3.0.8
  - tiles-request 1.0.6 -> 1.0.7
  - log4j 2.10.0 -> 2.11.1
  - jackson 2.9.5 -> 2.9.7
  - fluido-skin.version 1.6 -> 1.7
  - slf4j 1.7.12 -> 1.7.25
  - xtream 1.4.10 -> 1.4.11.1
  - jetty 6.1.9 -> 6.1.26 (last in 6.1.x line)
  - xerces 2.10.0 - > 2.12.0
  - org.owasp 3.1.1 -> 3.3.4
  - versions-maven-plugin 2.5 -> 2.7
  - doxia-core 1.7 -> 1.8
  - doxia-markdown 1.3 -> 1.7
  - freemarker 2.3.26-incubating -> 2.3.28
  - org.apache.felix.main 4.0.3 -> 4.6.1  (Note: most recent 4.x)
  - easymock 3.4 -> 3.5.1
  - javax.el 3.0 -> 3.0.1-b10
  - jasper 6.0.18 -> 6.0.53  (Note: most recent 6.0.x)
  - juli 6.0.18 -> 6.0.53    (Note: most recent 6.0.x)
  - commons-logging 1.1.3 -> 1.2
  - commons-collections4 4.1 -> 4.2
  - commons-io 2.5 -> 2.6
  - commons-lang 3.6 -> 3.8.1
  - commons-beanutils 1.9.2 -> 1.9.3
  - commons-validator 1.5.1 -> 1.6
  - mockito 1.9.5 -> 1.10.19            (Note: most recent 1.x)
  - cdi-api 1.0-SP1 -> 1.0-SP4          (Note: most recent 1.0.x)
  - weld-core 1.0.1-Final -> 1.0.1-SP4  (Note: most recent 1.0.x)
  Note for cglib-nodep:  Build succeeded with cglib-nodep 2.2.2 and 3.2.5.  Although
    cglib 3.2.5 matches ASM 5.2, jmock-cglib 1.2.0 identifies cglib-nodep 2.1_3 as its
    requirement (on the JMock http://jmock.org/download.html download page) so it should
    remain as long as JMock 1.2.0 is used.
2018-11-12 14:49:56 -05:00
JCgH4164838Gh792C124B5 478a9b8f1c Update Struts 2.5.19 build to use some newer (compatible) library versions.
- Fix SCM tag entry typo in main pom.xml.
- Enhance main pom.xml maven-surefire-plugin configuration to avoid some test-ng related duplication failures:
  "Cannot find JUnit method class junit.framework.TestSuite$1.warning".
- Remove unnecessary plugins/embeddedjsp/pom.xml (struts2-embeddedjsp-plugin) maven-surefire-plugin version override (noted with preceding change).
- Update Struts 2.5.19 build to use some newer (compatible) library versions.
  Change the main pom.xml library versions for the following:
  - spring.platformVersion 4.3.13.RELEASE -> 4.3.20.RELEASE
  - ognl 3.1.15 -> 3.1.18 (Note: newest version that passes unit tests)
  - oval 1.31 -> 1.90     (required unit test fix for OValValidationInterceptorTest.java)
  - tiles 3.0.7 -> 3.0.8
  - tiles-request 1.0.6 -> 1.0.7
  - log4j 2.10.0 -> 2.11.1
  - jackson 2.9.5 -> 2.9.7
  - fluido-skin.version 1.6 -> 1.7
  - slf4j 1.7.12 -> 1.7.25
  - xtream 1.4.10 -> 1.4.11.1
  - jetty 6.1.9 -> 6.1.26 (last in 6.1.x line)
  - xerces 2.10.0 - > 2.12.0
  - org.owasp 3.1.1 -> 3.3.4
  - versions-maven-plugin 2.5 -> 2.7
  - doxia-core 1.7 -> 1.8
  - doxia-markdown 1.3 -> 1.7
  - freemarker 2.3.26-incubating -> 2.3.28
  - org.apache.felix.main 4.0.3 -> 4.6.1  (most recent 4.x)
  - cglib 2.1_3 -> 3.2.5 (match for ASM 5.2)
  - easymock 3.4 -> 3.5.1
  - javax.el 3.0 -> 3.0.1-b10
  - jasper 6.0.18 -> 6.0.53 (most recent 6.0.x)
  - juli 6.0.18 -> 6.0.53 (most recent 6.0.x)
  - commons-logging 1.1.3 -> 1.2
  - commons-collections4 4.1 -> 4.2
  - commons-io 2.5 -> 2.6
  - commons-lang 3.6 -> 3.8.1
  - commons-beanutils 1.9.2 -> 1.9.3
  - commons-validator 1.5.1 -> 1.6
  - mockito 1.9.5 -> 1.10.19 (most recent 1.x)
  - cdi-api 1.0-SP1 -> 1.0-SP4 (most recent 1.0.x)
  - weld-core 1.0.1-Final -> 1.0.1-SP4 (most recent 1.0.x)
2018-11-12 13:49:51 -05:00
Lukasz Lenart 12c3d23bdf Merge pull request #260 from yasserzamani/WW-4974
WW-4974 monitor not-monitored loaded files on demand
2018-11-03 10:47:09 +01:00
Aleksandr Mashchenko 8293add6aa Merge pull request #257 from JCgH4164838Gh792C124B5/localS2_2_5_x_Branch
Fix WW-4971 (broken includes for non-UTF8 content).
2018-11-01 21:53:04 +02:00
Yasser Zamani ecb7beef38 not miss container provided fileUrl and ...
lazy monitoring for performance. Fix and test stopping reload configs at runtime.

Fixes WW-4974
2018-11-01 15:17:02 +03:30
Yasser Zamani bac0f2953c monitor not-monitored loaded files on demand
See WW-4974
2018-10-31 19:51:37 +03:30
JCgH4164838Gh792C124B5 7bca98205d Fix typos and whitespace (on top of WW-4971 Fix broken s:includes for non-UTF8 content). 2018-10-25 00:13:35 -04:00
JCgH4164838Gh792C124B5 567fae9dfc WW-4971 Fix broken s:includes for non-UTF8 content. The low-risk fix retains existing behaviour by default, but provides a configuration flag users can set (to true) in order to enable usage of response (page) encoding for s:include tags. A WARN level log output is also generated for failed FastByteArrayOutputStream decoding (can be suppressed by log configuration). 2018-10-24 23:41:38 -04:00
Lukasz Lenart f4d7dbe88e [maven-release-plugin] prepare for next development iteration 2018-09-18 11:23:59 +02:00
Lukasz Lenart 289782c583 [maven-release-plugin] prepare release STRUTS_2_5_18 2018-09-18 11:23:36 +02:00
Lukasz Lenart 1e33df947a WW-4951 Upgrades to the latest struts master to support SHA256/512 2018-09-18 09:49:27 +02:00
Lukasz Lenart de1a42d34a Merge pull request #250 from yasserzamani/WW-4948
WW-4948 delete temp files on close instead of on JVM exists
2018-09-17 08:02:35 +02:00
Yasser Zamani b816cc1374 monitor file only if needed
See also: WW-4948
2018-09-10 18:18:42 +04:30
Yasser Zamani b802baa4a9 delete temp files on close instead of on JVM exists 2018-09-06 12:59:21 +04:30
Aleksandr Mashchenko daac47ee62 Improve log messages in SecurityMemberAccess
(cherry picked from commit be1a93b0d5)
2018-09-03 21:51:30 +03:00
Aleksandr Mashchenko b1709c5208 Better logging message (for WW-4954)
(cherry picked from commit b213d58f54)
2018-09-03 21:51:17 +03:00
Yasser Zamani daf6f6f749 Merge pull request #244 from apache/WW-4954
WW-4954 Moves XWorkList out of util package
2018-08-31 16:23:02 +04:30
Lukasz Lenart 029892d656 WW-4954 Moves XWorkList out of util package 2018-08-30 08:39:11 +02:00
Lukasz Lenart 65fb0d4a44 Merge pull request #242 from benelog/fix-log-2-5-x
Fix logging  message (for 2.5.x)
2018-08-27 14:17:38 +02:00
Sanghyuk Jung 58d87025e9 Fix logging messages 2018-08-27 20:59:00 +09:00
Yaser Zamani 83c0f1cd1e [maven-release-plugin] prepare for next development iteration 2018-08-13 17:13:52 +04:30
Yaser Zamani eacc002334 [maven-release-plugin] prepare release STRUTS_2_5_17 2018-08-13 17:12:34 +04:30
Yasser Zamani 45effc3822 add an extra unit test 2018-06-29 16:28:23 +04:30
Lukasz Lenart bad9a49060 Fixes how dependencies are injected into constructor 2018-06-27 08:15:21 +02:00
Yasser Zamani a75eddb515 delete redundant code for performance 2018-06-21 12:00:46 +04:30
Lukasz Lenart 6e87474f9a Validates action, namespace and method in the same way 2018-06-21 09:19:57 +02:00
Lukasz Lenart 9fcbd912bc Adds more general exclusion 2018-06-21 08:20:11 +02:00
Lukasz Lenart fbc780e779 Adds proper handling of primitive types 2018-06-20 11:47:53 +02:00
Lukasz Lenart 6eb83016e3 Fixes wrong version in bom 2018-06-15 09:31:57 +02:00
Lukasz Lenart 3ec7fa9d80 Makes OgnlUtil more immutable 2018-05-29 12:58:44 +02:00
Lukasz Lenart f9806ee4e1 Adds Maven wrapper to allow use the latest Maven version 2018-05-29 11:48:39 +02:00
Lukasz Lenart d175836757 Changes version to snapshot 2018-05-02 08:45:44 +02:00
Lukasz Lenart e55ad3fb45 Upgrades Jackson libs to version 2.9.5 2018-05-02 08:35:52 +02:00
Lukasz Lenart 6efaf900d4 Increases scope when location parsing is avoided 2018-05-02 08:25:06 +02:00
Lukasz Lenart b3bad5ea44 Avoids parsing namespace when using existing namespace 2018-05-02 08:04:15 +02:00
114 changed files with 2541 additions and 548 deletions
+1
View File
@@ -62,3 +62,4 @@ bundles/target
plugins/target
target
plugins/testng/test-output
test-output
+110
View File
@@ -0,0 +1,110 @@
/*
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.*;
import java.util.Properties;
public class MavenWrapperDownloader {
/**
* 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/0.4.0/maven-wrapper-0.4.0.jar";
/**
* Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
* use instead of the default one.
*/
private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
".mvn/wrapper/maven-wrapper.properties";
/**
* Path where the maven-wrapper.jar will be saved to.
*/
private static final String MAVEN_WRAPPER_JAR_PATH =
".mvn/wrapper/maven-wrapper.jar";
/**
* Name of the property which should be used to override the default download url for the wrapper.
*/
private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
public static void main(String args[]) {
System.out.println("- Downloader started");
File baseDirectory = new File(args[0]);
System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
// If the maven-wrapper.properties exists, read it and check if it contains a custom
// wrapperUrl parameter.
File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
String url = DEFAULT_DOWNLOAD_URL;
if(mavenWrapperPropertyFile.exists()) {
FileInputStream mavenWrapperPropertyFileInputStream = null;
try {
mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
Properties mavenWrapperProperties = new Properties();
mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
} catch (IOException e) {
System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
} finally {
try {
if(mavenWrapperPropertyFileInputStream != null) {
mavenWrapperPropertyFileInputStream.close();
}
} catch (IOException e) {
// Ignore ...
}
}
}
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 direcrory '" + outputFile.getParentFile().getAbsolutePath() + "'");
}
}
System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
try {
downloadFileFromURL(url, outputFile);
System.out.println("Done");
System.exit(0);
} catch (Throwable e) {
System.out.println("- Error downloading");
e.printStackTrace();
System.exit(1);
}
}
private static void downloadFileFromURL(String urlString, File destination) throws Exception {
URL website = new URL(urlString);
ReadableByteChannel rbc;
rbc = Channels.newChannel(website.openStream());
FileOutputStream fos = new FileOutputStream(destination);
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
fos.close();
rbc.close();
}
}
BIN
View File
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.5.3/apache-maven-3.5.3-bin.zip
+8 -1
View File
@@ -4,12 +4,19 @@ sudo: false
jdk:
- openjdk7
- oraclejdk8
- oraclejdk9
- oraclejdk11
install: true
script: mvn test -DskipAssembly
after_success:
- mvn clean cobertura:cobertura org.eluder.coveralls:coveralls-maven-plugin:report com.updateimpact:updateimpact-maven-plugin:submit -Ptravis-coveralls,update-impact -DskipAssembly
# 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;
else
echo "Not reporting coverage for $TRAVIS_JDK_VERSION due to incompatibility or to save performance";
fi;
env:
global:
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-parent</artifactId>
<version>2.5.16</version>
<version>2.5.19</version>
</parent>
<artifactId>struts2-apps</artifactId>
<packaging>pom</packaging>
+2 -2
View File
@@ -24,12 +24,12 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-apps</artifactId>
<version>2.5.16</version>
<version>2.5.19</version>
</parent>
<artifactId>struts2-rest-showcase</artifactId>
<packaging>war</packaging>
<version>2.5.16</version>
<version>2.5.19</version>
<name>Struts 2 Rest Showcase Webapp</name>
<description>Struts 2 Rest Showcase Example</description>
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-apps</artifactId>
<version>2.5.16</version>
<version>2.5.19</version>
</parent>
<artifactId>struts2-showcase</artifactId>
+2 -2
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-parent</artifactId>
<version>2.5.16</version>
<version>2.5.19</version>
</parent>
<artifactId>struts2-assembly</artifactId>
@@ -111,7 +111,7 @@
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>attached</goal>
<goal>single</goal>
</goals>
</execution>
</executions>
+6 -6
View File
@@ -1,6 +1,6 @@
http://struts.apache.org/getting-started/
http://struts.apache.org/security/
http://struts.apache.org/core-developers/
http://struts.apache.org/tag-developers/
http://struts.apache.org/maven-archetypes/
http://struts.apache.org/plugins/
https://struts.apache.org/getting-started/
https://struts.apache.org/security/
https://struts.apache.org/core-developers/
https://struts.apache.org/tag-developers/
https://struts.apache.org/maven-archetypes/
https://struts.apache.org/plugins/
+3 -3
View File
@@ -30,7 +30,7 @@
</parent>
<artifactId>struts2-bom</artifactId>
<version>2.5.16</version>
<version>2.5.19</version>
<packaging>pom</packaging>
<name>Struts 2 Bill of Materials</name>
@@ -45,7 +45,7 @@
</licenses>
<properties>
<struts-version.version>2.5.16</struts-version.version>
<struts-version.version>2.5.19</struts-version.version>
<maven.site.skip>true</maven.site.skip>
<maven.site.deploy.skip>true</maven.site.deploy.skip>
</properties>
@@ -181,6 +181,6 @@
</dependencyManagement>
<scm>
<tag>STRUTS_2_5_16</tag>
<tag>STRUTS_2_5_19</tag>
</scm>
</project>
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-osgi-bundles</artifactId>
<version>2.5.16</version>
<version>2.5.19</version>
</parent>
<artifactId>struts2-osgi-admin-bundle</artifactId>
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-osgi-bundles</artifactId>
<version>2.5.16</version>
<version>2.5.19</version>
</parent>
<artifactId>struts2-osgi-demo-bundle</artifactId>
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-parent</artifactId>
<version>2.5.16</version>
<version>2.5.19</version>
</parent>
<artifactId>struts2-osgi-bundles</artifactId>
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-parent</artifactId>
<version>2.5.16</version>
<version>2.5.19</version>
</parent>
<artifactId>struts2-core</artifactId>
<packaging>jar</packaging>
@@ -201,13 +201,10 @@ public class ActionChainResult implements Result {
* @param invocation the DefaultActionInvocation calling the action call stack
*/
public void execute(ActionInvocation invocation) throws Exception {
// if the finalNamespace wasn't explicitly defined, assume the current one
if (this.namespace == null) {
this.namespace = invocation.getProxy().getNamespace();
}
ValueStack stack = ActionContext.getContext().getValueStack();
String finalNamespace = TextParseUtil.translateVariables(namespace, stack);
String finalNamespace = this.namespace != null
? TextParseUtil.translateVariables(namespace, stack)
: invocation.getProxy().getNamespace();
String finalActionName = TextParseUtil.translateVariables(actionName, stack);
String finalMethodName = this.methodName != null
? TextParseUtil.translateVariables(this.methodName, stack)
@@ -226,6 +226,7 @@ public class XWorkConfigurationProvider implements ConfigurationProvider {
props.setProperty(XWorkConstants.ENABLE_OGNL_EXPRESSION_CACHE, Boolean.TRUE.toString());
props.setProperty(XWorkConstants.ENABLE_OGNL_EVAL_EXPRESSION, Boolean.FALSE.toString());
props.setProperty(XWorkConstants.RELOAD_XML_CONFIGURATION, Boolean.FALSE.toString());
props.setProperty(StrutsConstants.STRUTS_ALLOW_STATIC_METHOD_ACCESS, Boolean.FALSE.toString());
}
}
@@ -21,7 +21,6 @@ package com.opensymphony.xwork2.conversion.impl;
import com.opensymphony.xwork2.conversion.ObjectTypeDeterminer;
import com.opensymphony.xwork2.conversion.TypeConverter;
import com.opensymphony.xwork2.inject.Inject;
import com.opensymphony.xwork2.util.XWorkList;
import java.lang.reflect.Member;
import java.util.Collection;
@@ -16,13 +16,12 @@
* specific language governing permissions and limitations
* under the License.
*/
package com.opensymphony.xwork2.util;
package com.opensymphony.xwork2.conversion.impl;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ObjectFactory;
import com.opensymphony.xwork2.XWorkException;
import com.opensymphony.xwork2.conversion.TypeConverter;
import com.opensymphony.xwork2.conversion.impl.XWorkConverter;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -23,7 +23,7 @@ package com.opensymphony.xwork2.ognl;
*/
public class ErrorMessageBuilder {
private StringBuilder message = new StringBuilder();
private final StringBuilder message = new StringBuilder();
public static ErrorMessageBuilder create() {
return new ErrorMessageBuilder();
@@ -24,7 +24,7 @@ import java.util.Map;
public class OgnlNullHandlerWrapper implements ognl.NullHandler {
private NullHandler wrapped;
private final NullHandler wrapped;
public OgnlNullHandlerWrapper(NullHandler target) {
this.wrapped = target;
@@ -28,7 +28,7 @@ import java.util.Map;
*/
public class OgnlTypeConverterWrapper implements ognl.TypeConverter {
private TypeConverter typeConverter;
private final TypeConverter typeConverter;
public OgnlTypeConverterWrapper(TypeConverter converter) {
if (converter == null) {
@@ -58,44 +58,61 @@ public class OgnlUtil {
private final ConcurrentMap<Class, BeanInfo> beanInfoCache = new ConcurrentHashMap<>();
private TypeConverter defaultConverter;
private boolean devMode = false;
private boolean devMode;
private boolean enableExpressionCache = true;
private boolean enableEvalExpression;
private Set<Class<?>> excludedClasses = Collections.emptySet();
private Set<Pattern> excludedPackageNamePatterns = Collections.emptySet();
private Set<String> excludedPackageNames = Collections.emptySet();
private Set<Class<?>> excludedClasses;
private Set<Pattern> excludedPackageNamePatterns;
private Set<String> excludedPackageNames;
private Container container;
private boolean allowStaticMethodAccess;
private boolean disallowProxyMemberAccess;
public OgnlUtil() {
excludedClasses = new HashSet<>();
excludedPackageNamePatterns = new HashSet<>();
excludedPackageNames = new HashSet<>();
}
@Inject
public void setXWorkConverter(XWorkConverter conv) {
protected void setXWorkConverter(XWorkConverter conv) {
this.defaultConverter = new OgnlTypeConverterWrapper(conv);
}
@Inject(XWorkConstants.DEV_MODE)
public void setDevMode(String mode) {
protected void setDevMode(String mode) {
this.devMode = BooleanUtils.toBoolean(mode);
if (this.devMode) {
LOG.warn("Setting development mode [{}] affects the safety of your application!",
this.devMode);
}
}
@Inject(XWorkConstants.ENABLE_OGNL_EXPRESSION_CACHE)
public void setEnableExpressionCache(String cache) {
protected void setEnableExpressionCache(String cache) {
enableExpressionCache = BooleanUtils.toBoolean(cache);
}
@Inject(value = XWorkConstants.ENABLE_OGNL_EVAL_EXPRESSION, required = false)
public void setEnableEvalExpression(String evalExpression) {
enableEvalExpression = "true".equals(evalExpression);
if(enableEvalExpression){
protected void setEnableEvalExpression(String evalExpression) {
this.enableEvalExpression = BooleanUtils.toBoolean(evalExpression);
if (this.enableEvalExpression) {
LOG.warn("Enabling OGNL expression evaluation may introduce security risks " +
"(see http://struts.apache.org/release/2.3.x/docs/s2-013.html for further details)");
}
}
@Inject(value = XWorkConstants.OGNL_EXCLUDED_CLASSES, required = false)
public void setExcludedClasses(String commaDelimitedClasses) {
protected void setExcludedClasses(String commaDelimitedClasses) {
Set<Class<?>> excludedClasses = new HashSet<>();
excludedClasses.addAll(this.excludedClasses);
excludedClasses.addAll(parseExcludedClasses(commaDelimitedClasses));
this.excludedClasses = Collections.unmodifiableSet(excludedClasses);
}
private Set<Class<?>> parseExcludedClasses(String commaDelimitedClasses) {
Set<String> classNames = TextParseUtil.commaDelimitedStringToSet(commaDelimitedClasses);
Set<Class<?>> classes = new HashSet<>();
@@ -107,11 +124,18 @@ public class OgnlUtil {
}
}
excludedClasses = Collections.unmodifiableSet(classes);
return classes;
}
@Inject(value = XWorkConstants.OGNL_EXCLUDED_PACKAGE_NAME_PATTERNS, required = false)
public void setExcludedPackageNamePatterns(String commaDelimitedPackagePatterns) {
protected void setExcludedPackageNamePatterns(String commaDelimitedPackagePatterns) {
Set<Pattern> excludedPackageNamePatterns = new HashSet<>();
excludedPackageNamePatterns.addAll(this.excludedPackageNamePatterns);
excludedPackageNamePatterns.addAll(parseExcludedPackageNamePatterns(commaDelimitedPackagePatterns));
this.excludedPackageNamePatterns = Collections.unmodifiableSet(excludedPackageNamePatterns);
}
private Set<Pattern> parseExcludedPackageNamePatterns(String commaDelimitedPackagePatterns) {
Set<String> packagePatterns = TextParseUtil.commaDelimitedStringToSet(commaDelimitedPackagePatterns);
Set<Pattern> packageNamePatterns = new HashSet<>();
@@ -119,12 +143,19 @@ public class OgnlUtil {
packageNamePatterns.add(Pattern.compile(pattern));
}
excludedPackageNamePatterns = Collections.unmodifiableSet(packageNamePatterns);
return packageNamePatterns;
}
@Inject(value = XWorkConstants.OGNL_EXCLUDED_PACKAGE_NAMES, required = false)
public void setExcludedPackageNames(String commaDelimitedPackageNames) {
excludedPackageNames = Collections.unmodifiableSet(TextParseUtil.commaDelimitedStringToSet(commaDelimitedPackageNames));
protected void setExcludedPackageNames(String commaDelimitedPackageNames) {
Set<String> excludedPackageNames = new HashSet<>();
excludedPackageNames.addAll(this.excludedPackageNames);
excludedPackageNames.addAll(parseExcludedPackageNames(commaDelimitedPackageNames));
this.excludedPackageNames = Collections.unmodifiableSet(excludedPackageNames);
}
private Set<String> parseExcludedPackageNames(String commaDelimitedPackageNames) {
return TextParseUtil.commaDelimitedStringToSet(commaDelimitedPackageNames);
}
public Set<Class<?>> getExcludedClasses() {
@@ -140,18 +171,27 @@ public class OgnlUtil {
}
@Inject
public void setContainer(Container container) {
protected void setContainer(Container container) {
this.container = container;
}
@Inject(value = XWorkConstants.ALLOW_STATIC_METHOD_ACCESS, required = false)
public void setAllowStaticMethodAccess(String allowStaticMethodAccess) {
this.allowStaticMethodAccess = Boolean.parseBoolean(allowStaticMethodAccess);
protected void setAllowStaticMethodAccess(String allowStaticMethodAccess) {
this.allowStaticMethodAccess = BooleanUtils.toBoolean(allowStaticMethodAccess);
if (this.allowStaticMethodAccess) {
LOG.warn("Setting allow static method access [{}] affects the safety of your application!",
this.allowStaticMethodAccess);
}
}
@Inject(value = StrutsConstants.STRUTS_DISALLOW_PROXY_MEMBER_ACCESS, required = false)
public void setDisallowProxyMemberAccess(String disallowProxyMemberAccess) {
protected void setDisallowProxyMemberAccess(String disallowProxyMemberAccess) {
this.disallowProxyMemberAccess = Boolean.parseBoolean(disallowProxyMemberAccess);
if (this.disallowProxyMemberAccess == false) {
LOG.warn("Setting disallow proxy member access [{}] should only be done intentionally!",
this.disallowProxyMemberAccess);
}
}
public boolean isDisallowProxyMemberAccess() {
@@ -404,7 +444,7 @@ public class OgnlUtil {
final T exec = task.execute(tree);
// if cache is enabled and it's a valid expression, puts it in
if(enableExpressionCache) {
if (enableExpressionCache) {
expressions.putIfAbsent(expression, tree);
}
return exec;
@@ -425,7 +465,7 @@ public class OgnlUtil {
final T exec = task.execute(tree);
// if cache is enabled and it's a valid expression, puts it in
if(enableExpressionCache) {
if (enableExpressionCache) {
expressions.putIfAbsent(expression, tree);
}
return exec;
@@ -641,8 +681,7 @@ public class OgnlUtil {
*/
public BeanInfo getBeanInfo(Class clazz) throws IntrospectionException {
synchronized (beanInfoCache) {
BeanInfo beanInfo;
beanInfo = beanInfoCache.get(clazz);
BeanInfo beanInfo = beanInfoCache.get(clazz);
if (beanInfo == null) {
beanInfo = Introspector.getBeanInfo(clazz, Object.class);
beanInfoCache.putIfAbsent(clazz, beanInfo);
@@ -82,7 +82,7 @@ public class OgnlValueStack implements Serializable, ValueStack, ClearableValueS
}
@Inject
public void setOgnlUtil(OgnlUtil ognlUtil) {
protected void setOgnlUtil(OgnlUtil ognlUtil) {
this.ognlUtil = ognlUtil;
securityMemberAccess.setExcludedClasses(ognlUtil.getExcludedClasses());
securityMemberAccess.setExcludedPackageNamePatterns(ognlUtil.getExcludedPackageNamePatterns());
@@ -102,12 +102,16 @@ public class OgnlValueStack implements Serializable, ValueStack, ClearableValueS
}
@Inject(XWorkConstants.DEV_MODE)
public void setDevMode(String mode) {
protected void setDevMode(String mode) {
this.devMode = BooleanUtils.toBoolean(mode);
if (this.devMode) {
LOG.warn("Setting development mode [{}] affects the safety of your application!",
this.devMode);
}
}
@Inject(value = "logMissingProperties", required = false)
public void setLogMissingProperties(String logMissingProperties) {
protected void setLogMissingProperties(String logMissingProperties) {
this.logMissingProperties = BooleanUtils.toBoolean(logMissingProperties);
}
@@ -379,7 +383,7 @@ public class OgnlValueStack implements Serializable, ValueStack, ClearableValueS
* @param e The thrown exception.
*/
private void logLookupFailure(String expr, Exception e) {
if (devMode && LOG.isWarnEnabled()) {
if (devMode) {
LOG.warn("Caught an exception while evaluating expression '{}' against value stack", expr, e);
LOG.warn("NOTE: Previous warning message was issued due to devMode set to true.");
} else {
@@ -475,7 +479,7 @@ public class OgnlValueStack implements Serializable, ValueStack, ClearableValueS
}
@Inject
public void setXWorkConverter(final XWorkConverter converter) {
protected void setXWorkConverter(final XWorkConverter converter) {
this.converter = converter;
}
}
@@ -32,6 +32,8 @@ import ognl.MethodAccessor;
import ognl.OgnlRuntime;
import ognl.PropertyAccessor;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.Map;
import java.util.Set;
@@ -41,25 +43,31 @@ import java.util.Set;
*/
public class OgnlValueStackFactory implements ValueStackFactory {
private static final Logger LOG = LogManager.getLogger(OgnlValueStackFactory.class);
protected XWorkConverter xworkConverter;
protected CompoundRootAccessor compoundRootAccessor;
protected TextProvider textProvider;
protected Container container;
protected boolean allowStaticMethodAccess;
private boolean allowStaticMethodAccess;
@Inject
public void setXWorkConverter(XWorkConverter converter) {
protected void setXWorkConverter(XWorkConverter converter) {
this.xworkConverter = converter;
}
@Inject("system")
public void setTextProvider(TextProvider textProvider) {
protected void setTextProvider(TextProvider textProvider) {
this.textProvider = textProvider;
}
@Inject(value="allowStaticMethodAccess", required=false)
public void setAllowStaticMethodAccess(String allowStaticMethodAccess) {
protected void setAllowStaticMethodAccess(String allowStaticMethodAccess) {
this.allowStaticMethodAccess = BooleanUtils.toBoolean(allowStaticMethodAccess);
if (this.allowStaticMethodAccess) {
LOG.warn("Setting allow static method access [{}] affects the safety of your application!",
this.allowStaticMethodAccess);
}
}
public ValueStack createValueStack() {
@@ -77,7 +85,7 @@ public class OgnlValueStackFactory implements ValueStackFactory {
}
@Inject
public void setContainer(Container container) throws ClassNotFoundException {
protected void setContainer(Container container) throws ClassNotFoundException {
Set<String> names = container.getInstanceNames(PropertyAccessor.class);
for (String name : names) {
Class cls = Class.forName(name);
@@ -46,9 +46,16 @@ public class SecurityMemberAccess extends DefaultMemberAccess {
private Set<String> excludedPackageNames = Collections.emptySet();
private boolean disallowProxyMemberAccess;
public SecurityMemberAccess(boolean method) {
/**
* SecurityMemberAccess
* - access decisions based on whether member is static (or not)
* - block or allow access to properties (configureable-after-construction)
*
* @param allowStaticMethodAccess
*/
public SecurityMemberAccess(boolean allowStaticMethodAccess) {
super(false);
allowStaticMethodAccess = method;
this.allowStaticMethodAccess = allowStaticMethodAccess;
}
public boolean getAllowStaticMethodAccess() {
@@ -59,28 +66,30 @@ public class SecurityMemberAccess extends DefaultMemberAccess {
public boolean isAccessible(Map context, Object target, Member member, String propertyName) {
LOG.debug("Checking access for [target: {}, member: {}, property: {}]", target, member, propertyName);
final Class memberClass = member.getDeclaringClass();
Class targetClass = (target != null ? target.getClass() : memberClass); // Note: target,propertyName may be null (static field checks OGNL 3.1.19+)
if (checkEnumAccess(target, member)) {
LOG.trace("Allowing access to enum: {}", target);
LOG.trace("Allowing access to enum: target class [{}] of target [{}], member [{}]", targetClass, target, member);
return true;
}
Class targetClass = target.getClass();
Class memberClass = member.getDeclaringClass();
if (Modifier.isStatic(member.getModifiers()) && allowStaticMethodAccess) {
LOG.debug("Support for accessing static methods [target: {}, member: {}, property: {}] is deprecated!", target, member, propertyName);
if (!isClassExcluded(member.getDeclaringClass())) {
targetClass = member.getDeclaringClass();
LOG.debug("Support for accessing static methods [target: {}, targetClass: {}, member: {}, property: {}] is deprecated!",
target, targetClass, member, propertyName);
if (!isClassExcluded(memberClass)) {
targetClass = memberClass;
}
}
if (isPackageExcluded(targetClass.getPackage(), memberClass.getPackage())) {
LOG.warn("Package of target [{}] or package of member [{}] are excluded!", target, member);
LOG.warn("Package [{}] of target class [{}] of target [{}] or package [{}] of member [{}] are excluded!", targetClass.getPackage(), targetClass,
target, memberClass.getPackage(), member);
return false;
}
if (isClassExcluded(targetClass)) {
LOG.warn("Target class [{}] is excluded!", target);
LOG.warn("Target class [{}] of target [{}] is excluded!", targetClass, target);
return false;
}
@@ -90,7 +99,7 @@ public class SecurityMemberAccess extends DefaultMemberAccess {
}
if (disallowProxyMemberAccess && ProxyUtil.isProxyMember(member, target)) {
LOG.warn("Access to proxy [{}] is blocked!", member);
LOG.warn("Access to proxy is blocked! Target class [{}] of target [{}], member [{}]", targetClass, target, member);
return false;
}
@@ -133,8 +142,8 @@ public class SecurityMemberAccess extends DefaultMemberAccess {
LOG.warn("The use of the default (unnamed) package is discouraged!");
}
final String targetPackageName = targetPackage == null ? "" : targetPackage.getName();
final String memberPackageName = memberPackage == null ? "" : memberPackage.getName();
String targetPackageName = targetPackage == null ? "" : targetPackage.getName();
String memberPackageName = memberPackage == null ? "" : memberPackage.getName();
for (Pattern pattern : excludedPackageNamePatterns) {
if (pattern.matcher(targetPackageName).matches() || pattern.matcher(memberPackageName).matches()) {
@@ -142,9 +151,11 @@ public class SecurityMemberAccess extends DefaultMemberAccess {
}
}
targetPackageName = targetPackageName + ".";
memberPackageName = memberPackageName + ".";
for (String packageName: excludedPackageNames) {
if (targetPackageName.startsWith(packageName) || targetPackageName.equals(packageName)
|| memberPackageName.startsWith(packageName) || memberPackageName.equals(packageName)) {
if (targetPackageName.startsWith(packageName) || memberPackageName.startsWith(packageName)) {
return true;
}
}
@@ -28,7 +28,7 @@ import java.util.Map;
*/
public class XWorkTypeConverterWrapper implements TypeConverter {
private ognl.TypeConverter typeConverter;
private final ognl.TypeConverter typeConverter;
public XWorkTypeConverterWrapper(ognl.TypeConverter conv) {
this.typeConverter = conv;
@@ -63,11 +63,15 @@ public class CompoundRootAccessor implements PropertyAccessor, MethodAccessor, C
private final static Logger LOG = LogManager.getLogger(CompoundRootAccessor.class);
private final static Class[] EMPTY_CLASS_ARRAY = new Class[0];
private static Map<MethodCall, Boolean> invalidMethods = new ConcurrentHashMap<>();
private boolean devMode = false;
private boolean devMode;
@Inject(XWorkConstants.DEV_MODE)
public void setDevMode(String mode) {
protected void setDevMode(String mode) {
this.devMode = BooleanUtils.toBoolean(mode);
if (this.devMode) {
LOG.warn("Setting development mode [{}] affects the safety of your application!",
this.devMode);
}
}
public void setProperty(Map context, Object target, Object name, Object value) throws OgnlException {
@@ -48,7 +48,7 @@ public class XWorkCollectionPropertyAccessor extends SetPropertyAccessor {
//use a basic object Ognl property accessor here
//to access properties of the objects in the Set
//so that nothing is put in the context to screw things up
private ObjectPropertyAccessor _accessor = new ObjectPropertyAccessor();
private final ObjectPropertyAccessor _accessor = new ObjectPropertyAccessor();
private XWorkConverter xworkConverter;
private ObjectFactory objectFactory;
@@ -30,7 +30,7 @@ import java.util.Map;
*/
public class XWorkEnumerationAccessor extends EnumerationPropertyAccessor {
ObjectPropertyAccessor opa = new ObjectPropertyAccessor();
private final ObjectPropertyAccessor opa = new ObjectPropertyAccessor();
@Override
public void setProperty(Map context, Object target, Object name, Object value) throws OgnlException {
@@ -30,7 +30,7 @@ import java.util.Map;
*/
public class XWorkIteratorPropertyAccessor extends IteratorPropertyAccessor {
ObjectPropertyAccessor opa = new ObjectPropertyAccessor();
private final ObjectPropertyAccessor opa = new ObjectPropertyAccessor();
@Override
public void setProperty(Map context, Object target, Object name, Object value) throws OgnlException {
@@ -44,9 +44,9 @@ public class DefaultAcceptedPatternsChecker implements AcceptedPatternsChecker {
}
@Inject(value = XWorkConstants.OVERRIDE_ACCEPTED_PATTERNS, required = false)
public void setOverrideAcceptedPatterns(String acceptablePatterns) {
protected void setOverrideAcceptedPatterns(String acceptablePatterns) {
LOG.warn("Overriding accepted patterns [{}] with [{}], be aware that this affects all instances and safety of your application!",
XWorkConstants.OVERRIDE_ACCEPTED_PATTERNS, acceptablePatterns);
acceptedPatterns, acceptablePatterns);
acceptedPatterns = new HashSet<>();
for (String pattern : TextParseUtil.commaDelimitedStringToSet(acceptablePatterns)) {
acceptedPatterns.add(Pattern.compile(pattern, Pattern.CASE_INSENSITIVE));
@@ -54,7 +54,7 @@ public class DefaultAcceptedPatternsChecker implements AcceptedPatternsChecker {
}
@Inject(value = XWorkConstants.ADDITIONAL_ACCEPTED_PATTERNS, required = false)
public void setAdditionalAcceptedPatterns(String acceptablePatterns) {
protected void setAdditionalAcceptedPatterns(String acceptablePatterns) {
LOG.warn("Adding additional global patterns [{}] to accepted patterns!", acceptablePatterns);
for (String pattern : TextParseUtil.commaDelimitedStringToSet(acceptablePatterns)) {
acceptedPatterns.add(Pattern.compile(pattern, Pattern.CASE_INSENSITIVE));
@@ -70,7 +70,14 @@ public class DefaultAcceptedPatternsChecker implements AcceptedPatternsChecker {
}
public void setAcceptedPatterns(Set<String> patterns) {
LOG.trace("Sets accepted patterns [{}]", patterns);
if (acceptedPatterns == null) {
// Limit unwanted log entries (for 1st call, acceptedPatterns null)
LOG.debug("Sets accepted patterns to [{}], note this impacts the safety of your application!", patterns);
}
else {
LOG.warn("Replacing accepted patterns [{}] with [{}], be aware that this affects all instances and safety of your application!",
acceptedPatterns, patterns);
}
acceptedPatterns = new HashSet<>(patterns.size());
for (String pattern : patterns) {
acceptedPatterns.add(Pattern.compile(pattern, Pattern.CASE_INSENSITIVE));
@@ -47,9 +47,15 @@ public class DefaultExcludedPatternsChecker implements ExcludedPatternsChecker {
}
@Inject(value = XWorkConstants.OVERRIDE_EXCLUDED_PATTERNS, required = false)
public void setOverrideExcludePatterns(String excludePatterns) {
LOG.warn("Overriding excluded patterns [{}] with [{}], be aware that this affects all instances and safety of your application!",
XWorkConstants.OVERRIDE_EXCLUDED_PATTERNS, excludePatterns);
protected void setOverrideExcludePatterns(String excludePatterns) {
if (excludedPatterns != null && excludedPatterns.size() > 0) {
LOG.warn("Overriding excluded patterns [{}] with [{}], be aware that this affects all instances and safety of your application!",
excludedPatterns, excludePatterns);
}
else {
// Limit unwanted log entries (when excludedPatterns null/empty - usually 1st call)
LOG.debug("Overriding excluded patterns with [{}]", excludePatterns);
}
excludedPatterns = new HashSet<Pattern>();
for (String pattern : TextParseUtil.commaDelimitedStringToSet(excludePatterns)) {
excludedPatterns.add(Pattern.compile(pattern, Pattern.CASE_INSENSITIVE));
@@ -65,11 +71,14 @@ public class DefaultExcludedPatternsChecker implements ExcludedPatternsChecker {
}
@Inject(StrutsConstants.STRUTS_ENABLE_DYNAMIC_METHOD_INVOCATION)
public void setDynamicMethodInvocation(String dmiValue) {
if (!BooleanUtils.toBoolean(dmiValue)) {
protected void setDynamicMethodInvocation(String dmiValue) {
if (BooleanUtils.toBoolean(dmiValue) == false) {
LOG.debug("DMI is disabled, adding DMI related excluded patterns");
setAdditionalExcludePatterns("^(action|method):.*");
}
else {
LOG.warn("DMI is enabled, *NOT* adding DMI related excluded patterns");
}
}
public void setExcludedPatterns(String commaDelimitedPatterns) {
@@ -81,7 +90,14 @@ public class DefaultExcludedPatternsChecker implements ExcludedPatternsChecker {
}
public void setExcludedPatterns(Set<String> patterns) {
LOG.trace("Sets excluded patterns [{}]", patterns);
if (excludedPatterns != null && excludedPatterns.size() > 0) {
LOG.warn("Replacing excluded patterns [{}] with [{}], be aware that this affects all instances and safety of your application!",
excludedPatterns, patterns);
}
else {
// Limit unwanted log entries (when excludedPatterns null/empty - usually 1st call)
LOG.debug("Sets excluded patterns to [{}]", patterns);
}
excludedPatterns = new HashSet<>(patterns.size());
for (String pattern : patterns) {
excludedPatterns.add(Pattern.compile(pattern, Pattern.CASE_INSENSITIVE));
@@ -27,6 +27,7 @@ import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Collections;
import java.util.HashMap;
import java.util.Vector;
import java.util.zip.ZipEntry;
@@ -77,11 +78,7 @@ public class ClassPathFinder {
*/
public Vector<String> findMatches() {
Vector<String> matches = new Vector<>();
URLClassLoader cl = getURLClassLoader();
if (cl == null ) {
throw new XWorkException("unable to attain an URLClassLoader") ;
}
URL[] parentUrls = cl.getURLs();
URL[] parentUrls = getClassLoaderURLs();
compiledPattern = patternMatcher.compilePattern(pattern);
for (URL url : parentUrls) {
if (!"file".equals(url.getProtocol())) {
@@ -173,20 +170,24 @@ public class ClassPathFinder {
this.patternMatcher = patternMatcher;
}
private URLClassLoader getURLClassLoader() {
URLClassLoader ucl = null;
private URL[] getClassLoaderURLs() {
URL[] urls;
ClassLoader loader = Thread.currentThread().getContextClassLoader();
if(! (loader instanceof URLClassLoader)) {
if (!(loader instanceof URLClassLoader)) {
loader = ClassPathFinder.class.getClassLoader();
if (loader instanceof URLClassLoader) {
ucl = (URLClassLoader) loader ;
}
if (loader instanceof URLClassLoader) {
urls = ((URLClassLoader) loader).getURLs();
} else { //jdk9 or later
try {
urls = Collections.list(loader.getResources("")).toArray(new URL[0]);
} catch (IOException e) {
throw new XWorkException("unable to get ClassLoader URLs", e);
}
}
else {
ucl = (URLClassLoader) loader;
}
return ucl ;
return urls;
}
}
@@ -40,7 +40,8 @@ public class DefaultFileManager implements FileManager {
private static final Pattern JAR_PATTERN = Pattern.compile("^(jar:|wsjar:|zip:|vfsfile:|code-source:)?(file:)?(.*?)(\\!/|\\.jar/)(.*)");
private static final int JAR_FILE_PATH = 3;
protected static Map<String, Revision> files = Collections.synchronizedMap(new HashMap<String, Revision>());
protected static final Map<String, Revision> files = Collections.synchronizedMap(new HashMap<String, Revision>());
private static final List<URL> lazyMonitoredFilesCache = Collections.synchronizedList(new ArrayList<URL>());
protected boolean reloadingConfigs = false;
@@ -48,6 +49,16 @@ public class DefaultFileManager implements FileManager {
}
public void setReloadingConfigs(boolean reloadingConfigs) {
if (reloadingConfigs && !this.reloadingConfigs) {
//starting monitoring cached not-monitored files (lazy monitoring on demand because of performance)
this.reloadingConfigs = true;
synchronized (lazyMonitoredFilesCache) {
for (URL fileUrl : lazyMonitoredFilesCache) {
monitorFile(fileUrl);
}
lazyMonitoredFilesCache.clear();
}
}
this.reloadingConfigs = reloadingConfigs;
}
@@ -88,6 +99,12 @@ public class DefaultFileManager implements FileManager {
public void monitorFile(URL fileUrl) {
String fileName = fileUrl.toString();
if (!reloadingConfigs) {
//reserve file for monitoring on demand because of performance
files.remove(fileName);
lazyMonitoredFilesCache.add(fileUrl);
return;
}
Revision revision;
LOG.debug("Creating revision for URL: {}", fileName);
if (isJarURL(fileUrl)) {
@@ -37,9 +37,7 @@ public class JarEntryRevision extends Revision {
private long lastModified;
public static Revision build(URL fileUrl, FileManager fileManager) {
StrutsJarURLConnection conn = null;
try {
conn = StrutsJarURLConnection.openConnection(fileUrl);
try (StrutsJarURLConnection conn = StrutsJarURLConnection.openConnection(fileUrl)) {
conn.setUseCaches(false);
URL url = fileManager.normalizeToFileProtocol(fileUrl);
if (url != null) {
@@ -51,14 +49,6 @@ public class JarEntryRevision extends Revision {
LOG.warn("Could not create JarEntryRevision for [{}]!", fileUrl, e);
return null;
}
finally {
if(null != conn) {
try {
conn.getInputStream().close();
} catch (IOException ignored) {
}
}
}
}
private JarEntryRevision(URL jarFileURL, long lastModified) {
@@ -70,21 +60,12 @@ public class JarEntryRevision extends Revision {
}
public boolean needsReloading() {
StrutsJarURLConnection conn = null;
long lastLastModified = lastModified;
try {
conn = StrutsJarURLConnection.openConnection(jarFileURL);
try (StrutsJarURLConnection conn = StrutsJarURLConnection.openConnection(jarFileURL)) {
conn.setUseCaches(false);
lastLastModified = conn.getJarEntry().getTime();
} catch (IOException ignored) {
}
finally {
if(null != conn) {
try {
conn.getInputStream().close();
} catch (IOException ignored) {
}
}
} catch (Throwable e) {
LOG.warn("Could not check if needsReloading for [{}]!", jarFileURL, e);
}
return lastModified < lastLastModified;
@@ -44,7 +44,7 @@ import java.util.jar.JarFile;
* While {@link JarURLConnection#parseSpecs(URL)} is private, then we had to extend {@link URLConnection} instead
* @since 2.5.15
*/
class StrutsJarURLConnection extends URLConnection {
class StrutsJarURLConnection extends URLConnection implements AutoCloseable {
private static final String FILE_URL_PREFIX = "file:";
private JarURLConnection jarURLConnection;
@@ -123,8 +123,8 @@ class StrutsJarURLConnection extends URLConnection {
Path tmpFile = Files.createTempFile("jar_cache", null);
try {
Files.copy(in, tmpFile, StandardCopyOption.REPLACE_EXISTING);
JarFile jarFile = new JarFile(tmpFile.toFile(), true, JarFile.OPEN_READ);
tmpFile.toFile().deleteOnExit();
JarFile jarFile = new JarFile(tmpFile.toFile(), true, JarFile.OPEN_READ
| JarFile.OPEN_DELETE);
return jarFile;
} catch (Throwable thr) {
try {
@@ -171,6 +171,20 @@ class StrutsJarURLConnection extends URLConnection {
}
}
@Override
public void close() throws Exception {
try {
getInputStream().close();
} catch (IOException ignored) {
}
if (jarURLConnection == null) {
try {
jarFile.close();
} catch (IOException ignored) {
}
}
}
static StrutsJarURLConnection openConnection(URL url) throws IOException {
return new StrutsJarURLConnection(url);
}
@@ -41,12 +41,15 @@ public final class StrutsConstants {
/** The URL extension to use to determine if the request is meant for a Struts action */
public static final String STRUTS_ACTION_EXTENSION = "struts.action.extension";
/** Comma separated list of patterns (java.util.regex.Pattern) to be excluded from Struts2-processing */
public static final String STRUTS_ACTION_EXCLUDE_PATTERN = "struts.action.excludePattern";
/** Comma separated list of patterns (java.util.regex.Pattern) to be excluded from Struts2-processing */
public static final String STRUTS_ACTION_EXCLUDE_PATTERN = "struts.action.excludePattern";
/** Whether to use the alterative syntax for the tags or not */
/** Whether to use the alternative syntax for the tags or not */
public static final String STRUTS_TAG_ALTSYNTAX = "struts.tag.altSyntax";
/** Whether to use the response encoding (JSP page encoding) for s:include tag processing (false - use STRUTS_I18N_ENCODING - by default) */
public static final String STRUTS_TAG_INCLUDETAG_USERESPONSEENCODING = "struts.tag.includetag.useResponseEncoding";
/** The HTTP port used by Struts URLs */
public static final String STRUTS_URL_HTTP_PORT = "struts.url.http.port";
@@ -56,7 +59,7 @@ public final class StrutsConstants {
/** The default includeParams method to generate Struts URLs */
public static final String STRUTS_URL_INCLUDEPARAMS = "struts.url.includeParams";
public static final String STRUTS_URL_RENDERER = "struts.urlRenderer";
public static final String STRUTS_URL_RENDERER = "struts.urlRenderer";
/** The com.opensymphony.xwork2.ObjectFactory implementation class */
public static final String STRUTS_OBJECTFACTORY = "struts.objectFactory";
@@ -91,7 +94,7 @@ public final class StrutsConstants {
/** The org.apache.struts2.views.freemarker.FreemarkerManager implementation class */
public static final String STRUTS_FREEMARKER_MANAGER_CLASSNAME = "struts.freemarker.manager.classname";
/** Update freemarker templates cache in seconds*/
/** Update freemarker templates cache in seconds */
public static final String STRUTS_FREEMARKER_TEMPLATES_CACHE_UPDATE_DELAY = "struts.freemarker.templatesCache.updateDelay";
/** Cache model instances at BeanWrapper level */
@@ -220,12 +223,12 @@ public final class StrutsConstants {
public static final String STRUTS_LOCALE_PROVIDER_FACTORY = "struts.localeProviderFactory";
/** The name of the parameter to create when mapping an id (used by some action mappers) */
public static final String STRUTS_ID_PARAMETER_NAME = "struts.mapper.idParameterName";
/** The name of the parameter to determine whether static method access will be allowed in OGNL expressions or not */
public static final String STRUTS_ALLOW_STATIC_METHOD_ACCESS = "struts.ognl.allowStaticMethodAccess";
public static final String STRUTS_ID_PARAMETER_NAME = "struts.mapper.idParameterName";
/** The com.opensymphony.xwork2.validator.ActionValidatorManager implementation class */
/** The name of the parameter to determine whether static method access will be allowed in OGNL expressions or not */
public static final String STRUTS_ALLOW_STATIC_METHOD_ACCESS = "struts.ognl.allowStaticMethodAccess";
/** The com.opensymphony.xwork2.validator.ActionValidatorManager implementation class */
public static final String STRUTS_ACTIONVALIDATORMANAGER = "struts.actionValidatorManager";
/** The {@link com.opensymphony.xwork2.util.ValueStackFactory} implementation class */
@@ -236,7 +239,7 @@ public final class StrutsConstants {
/** The {@link com.opensymphony.xwork2.util.reflection.ReflectionContextFactory} implementation class */
public static final String STRUTS_REFLECTIONCONTEXTFACTORY = "struts.reflectionContextFactory";
/** The {@link com.opensymphony.xwork2.util.PatternMatcher} implementation class */
public static final String STRUTS_PATTERNMATCHER = "struts.patternMatcher";
@@ -246,32 +249,32 @@ public final class StrutsConstants {
/** The {@link com.opensymphony.xwork2.UnknownHandlerManager} implementation class */
public static final String STRUTS_UNKNOWN_HANDLER_MANAGER = "struts.unknownHandlerManager";
/** Throw RuntimeException when a property is not found, or the evaluation of the espression fails*/
/** Throw RuntimeException when a property is not found, or the evaluation of the expression fails */
public static final String STRUTS_EL_THROW_EXCEPTION = "struts.el.throwExceptionOnFailure";
/** Logs properties that are not found (very verbose) **/
/** Logs properties that are not found (very verbose) */
public static final String STRUTS_LOG_MISSING_PROPERTIES = "struts.ognl.logMissingProperties";
/** Enables caching of parsed OGNL expressions **/
/** Enables caching of parsed OGNL expressions */
public static final String STRUTS_ENABLE_OGNL_EXPRESSION_CACHE = "struts.ognl.enableExpressionCache";
/** Enables evaluation of OGNL expressions **/
/** Enables evaluation of OGNL expressions */
public static final String STRUTS_ENABLE_OGNL_EVAL_EXPRESSION = "struts.ognl.enableOGNLEvalExpression";
/** Disables {@link org.apache.struts2.dispatcher.StrutsRequestWrapper} request attribute value stack lookup (JSTL accessibility) **/
/** Disables {@link org.apache.struts2.dispatcher.StrutsRequestWrapper} request attribute value stack lookup (JSTL accessibility) */
public static final String STRUTS_DISABLE_REQUEST_ATTRIBUTE_VALUE_STACK_LOOKUP = "struts.disableRequestAttributeValueStackLookup";
/** The{@link org.apache.struts2.views.util.UrlHelper} implementation class **/
/** The{@link org.apache.struts2.views.util.UrlHelper} implementation class */
public static final String STRUTS_URL_HELPER = "struts.view.urlHelper";
/** {@link com.opensymphony.xwork2.conversion.impl.XWorkBasicConverter} **/
/** {@link com.opensymphony.xwork2.conversion.impl.XWorkBasicConverter} */
public static final String STRUTS_CONVERTER_COLLECTION = "struts.converter.collection";
public static final String STRUTS_CONVERTER_ARRAY = "struts.converter.array";
public static final String STRUTS_CONVERTER_DATE = "struts.converter.date";
public static final String STRUTS_CONVERTER_NUMBER = "struts.converter.number";
public static final String STRUTS_CONVERTER_STRING = "struts.converter.string";
/** Enable handling exceptions by Dispatcher - true by default **/
/** Enable handling exceptions by Dispatcher - true by default */
public static final String STRUTS_HANDLE_EXCEPTION = "struts.handle.exception";
public static final String STRUTS_CONVERTER_PROPERTIES_PROCESSOR = "struts.converter.properties.processor";
@@ -282,37 +285,42 @@ public final class StrutsConstants {
public static final String STRUTS_EXPRESSION_PARSER = "struts.expression.parser";
/** actions names' whitelist **/
/** Namespace names' whitelist */
public static final String STRUTS_ALLOWED_NAMESPACE_NAMES = "struts.allowed.namespace.names";
/** Default namespace name to use when namespace didn't match the whitelist */
public static final String STRUTS_DEFAULT_NAMESPACE_NAME = "struts.default.namespace.name";
/** Action names' whitelist */
public static final String STRUTS_ALLOWED_ACTION_NAMES = "struts.allowed.action.names";
/** default action name to use when action didn't match the whitelist **/
/** Default action name to use when action didn't match the whitelist */
public static final String STRUTS_DEFAULT_ACTION_NAME = "struts.default.action.name";
/** methods names' whitelist **/
/** Method names' whitelist */
public static final String STRUTS_ALLOWED_METHOD_NAMES = "struts.allowed.method.names";
/** default method name to use when method didn't match the whitelist **/
/** Default method name to use when method didn't match the whitelist */
public static final String STRUTS_DEFAULT_METHOD_NAME = "struts.default.method.name";
/** enables action: prefix **/
/** Enables action: prefix */
public static final String STRUTS_MAPPER_ACTION_PREFIX_ENABLED = "struts.mapper.action.prefix.enabled";
/** enables access to actions in other namespaces than current with action: prefix **/
/** Enables access to actions in other namespaces than current with action: prefix */
public static final String STRUTS_MAPPER_ACTION_PREFIX_CROSSNAMESPACES = "struts.mapper.action.prefix.crossNamespaces";
public static final String DEFAULT_TEMPLATE_TYPE_CONFIG_KEY = "struts.ui.templateSuffix";
/** Allows override default DispatcherErrorHandler **/
/** Allows override default DispatcherErrorHandler */
public static final String STRUTS_DISPATCHER_ERROR_HANDLER = "struts.dispatcher.errorHandler";
/** Comma delimited set of excluded classes and package names which cannot be accessed via expressions **/
/** Comma delimited set of excluded classes and package names which cannot be accessed via expressions */
public static final String STRUTS_EXCLUDED_CLASSES = "struts.excludedClasses";
public static final String STRUTS_EXCLUDED_PACKAGE_NAME_PATTERNS = "struts.excludedPackageNamePatterns";
public static final String STRUTS_EXCLUDED_PACKAGE_NAMES = "struts.excludedPackageNames";
/** Dedicated services to check if passed string is excluded/accepted **/
/** Dedicated services to check if passed string is excluded/accepted */
public static final String STRUTS_EXCLUDED_PATTERNS_CHECKER = "struts.excludedPatterns.checker";
public static final String STRUTS_ACCEPTED_PATTERNS_CHECKER = "struts.acceptedPatterns.checker";
/** Constant is used to override framework's default excluded patterns **/
/** Constant is used to override framework's default excluded patterns */
public static final String STRUTS_OVERRIDE_EXCLUDED_PATTERNS = "struts.override.excludedPatterns";
public static final String STRUTS_OVERRIDE_ACCEPTED_PATTERNS = "struts.override.acceptedPatterns";
@@ -20,6 +20,7 @@ package org.apache.struts2.components;
import com.opensymphony.xwork2.inject.Inject;
import com.opensymphony.xwork2.util.ValueStack;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.struts2.RequestUtils;
@@ -35,6 +36,7 @@ import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.*;
import java.net.URLEncoder;
import java.util.*;
@@ -90,17 +92,19 @@ public class Include extends Component {
private static final Logger LOG = LogManager.getLogger(Include.class);
private static String systemEncoding = System.getProperty("file.encoding");
private static final String systemEncoding = System.getProperty("file.encoding");
protected String value;
private HttpServletRequest req;
private HttpServletResponse res;
private static String defaultEncoding;
private String defaultEncoding; // Made non-static (during WW-4971 fix)
private boolean useResponseEncoding; // Added with WW-4971 fix (allows switch between usage of response or default encoding)
public Include(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
super(stack);
this.req = req;
this.res = res;
useResponseEncoding = false; // By default use defaultEncoding (vs. response/page encoding)
}
@Inject(StrutsConstants.STRUTS_I18N_ENCODING)
@@ -108,9 +112,25 @@ public class Include extends Component {
defaultEncoding = encoding;
}
@Inject(value = StrutsConstants.STRUTS_TAG_INCLUDETAG_USERESPONSEENCODING, required=false)
public void setUseResponseEncoding(String useEncoding) {
useResponseEncoding = Boolean.parseBoolean(useEncoding);
}
public boolean end(Writer writer, String body) {
String page = findString(value, "value", "You must specify the URL to include. Example: /foo.jsp");
StringBuilder urlBuf = new StringBuilder();
String encodingForInclude;
if (useResponseEncoding) {
encodingForInclude = res.getCharacterEncoding(); // Use response (page) encoding
if (encodingForInclude == null || encodingForInclude.length() == 0) {
encodingForInclude = defaultEncoding; // Revert to defaultEncoding when response (page) encoding is invalid
}
}
else {
encodingForInclude = defaultEncoding; // Use default encoding (when useResponseEncoding is false)
}
// Add URL
urlBuf.append(page);
@@ -147,7 +167,7 @@ public class Include extends Component {
// Include
try {
include(result, writer, req, res, defaultEncoding);
include(result, writer, req, res, encodingForInclude);
} catch (ServletException | IOException e) {
LOG.warn("Exception thrown during include of {}", result, e);
}
@@ -209,7 +229,7 @@ public class Include extends Component {
}
public void addParameter(String key, Object value) {
// don't use the default implementation of addParameter,
// Don't use the default implementation of addParameter,
// instead, include tag requires that each parameter be a list of objects,
// just like the HTTP servlet interfaces are (String[])
if (value != null) {
@@ -256,7 +276,7 @@ public class Include extends Component {
// Use given encoding
pageResponse.getContent().writeTo(writer, encoding);
} else {
//use the platform specific encoding
// Use the platform specific encoding
pageResponse.getContent().writeTo(writer, systemEncoding);
}
}
@@ -349,9 +369,9 @@ public class Include extends Component {
* @throws IOException
*/
public FastByteArrayOutputStream getContent() throws IOException {
//if we are using a writer, we need to flush the
//data to the underlying outputstream.
//most containers do this - but it seems Jetty 4.0.5 doesn't
// If we are using a writer, we need to flush the
// data to the underlying outputstream.
// Most containers do this - but it seems Jetty 4.0.5 doesn't
if (pagePrintWriter != null) {
pagePrintWriter.flush();
}
@@ -140,4 +140,19 @@ public class OptGroup extends Component {
public void setListValue(String listValue) {
internalUiBean.setListValue(listValue);
}
@StrutsTagAttribute(description = "Property of list objects to get css class from")
public void setListCssClass(String listCssClass) {
internalUiBean.setListCssClass(listCssClass);
}
@StrutsTagAttribute(description = "Property of list objects to get css style from")
public void setListCssStyle(String listCssStyle) {
internalUiBean.setListCssStyle(listCssStyle);
}
@StrutsTagAttribute(description = "Property of list objects to get title from")
public void setListTitle(String listTitle) {
internalUiBean.setListTitle(listTitle);
}
}
@@ -83,6 +83,7 @@ import com.opensymphony.xwork2.util.ValueStack;
public class Set extends ContextBean {
protected String scope;
protected String value;
protected boolean trimBody = true;
public Set(ValueStack stack) {
super(stack);
@@ -136,6 +137,11 @@ public class Set extends ContextBean {
this.value = value;
}
@StrutsTagAttribute(description="Set to false to prevent the default whitespace-trim of this tag's body content", type="Boolean", defaultValue="true")
public void setTrimBody(boolean trimBody) {
this.trimBody = trimBody;
}
@Override
public boolean usesBody() {
return true;
@@ -31,7 +31,6 @@ import org.apache.logging.log4j.Logger;
import org.apache.struts2.RequestUtils;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.StrutsConstants;
import org.apache.struts2.StrutsException;
import org.apache.struts2.util.PrefixTrie;
import javax.servlet.http.HttpServletRequest;
@@ -117,6 +116,10 @@ public class DefaultActionMapper implements ActionMapper {
protected boolean allowSlashesInActionNames = false;
protected boolean alwaysSelectFullNamespace = false;
protected PrefixTrie prefixTrie = null;
protected Pattern allowedNamespaceNames = Pattern.compile("[a-zA-Z0-9._/\\-]*");
protected String defaultNamespaceName = "/";
protected Pattern allowedActionNames = Pattern.compile("[a-zA-Z0-9._!/\\-]*");
protected String defaultActionName = "index";
@@ -202,6 +205,16 @@ public class DefaultActionMapper implements ActionMapper {
this.alwaysSelectFullNamespace = BooleanUtils.toBoolean(alwaysSelectFullNamespace);
}
@Inject(value = StrutsConstants.STRUTS_ALLOWED_NAMESPACE_NAMES, required = false)
public void setAllowedNamespaceNames(String allowedNamespaceNames) {
this.allowedNamespaceNames = Pattern.compile(allowedNamespaceNames);
}
@Inject(value = StrutsConstants.STRUTS_DEFAULT_NAMESPACE_NAME, required = false)
public void setDefaultNamespaceName(String defaultNamespaceName) {
this.defaultNamespaceName = defaultNamespaceName;
}
@Inject(value = StrutsConstants.STRUTS_ALLOWED_ACTION_NAMES, required = false)
public void setAllowedActionNames(String allowedActionNames) {
this.allowedActionNames = Pattern.compile(allowedActionNames);
@@ -389,10 +402,28 @@ public class DefaultActionMapper implements ActionMapper {
}
}
mapping.setNamespace(namespace);
mapping.setNamespace(cleanupNamespaceName(namespace));
mapping.setName(cleanupActionName(name));
}
/**
* Checks namespace name against allowed pattern if not matched returns default namespace
*
* @param rawNamespace name extracted from URI
* @return safe namespace name
*/
protected String cleanupNamespaceName(final String rawNamespace) {
if (allowedNamespaceNames.matcher(rawNamespace).matches()) {
return rawNamespace;
} else {
LOG.warn(
"{} did not match allowed namespace names {} - default namespace {} will be used!",
rawNamespace, allowedNamespaceNames, defaultNamespaceName
);
return defaultNamespaceName;
}
}
/**
* Checks action name against allowed pattern if not matched returns default action name
*
@@ -134,6 +134,7 @@ public class PostbackResult extends StrutsResultSupport {
if (actionName != null) {
actionName = conditionalParse(actionName, invocation);
parseLocation = false;
if (namespace == null) {
namespace = invocation.getProxy().getNamespace();
} else {
@@ -159,6 +159,7 @@ public class ServletActionRedirectResult extends ServletRedirectResult implement
*/
public void execute(ActionInvocation invocation) throws Exception {
actionName = conditionalParse(actionName, invocation);
parseLocation = false;
if (namespace == null) {
namespace = invocation.getProxy().getNamespace();
} else {
@@ -122,6 +122,8 @@ public abstract class StrutsResultSupport implements Result, StrutsStatics {
/** use UTF-8 as this is the recommended encoding by W3C to avoid incompatibilities. */
public static final String DEFAULT_URL_ENCODING = "UTF-8";
protected boolean parseLocation = true;
private boolean parse;
private boolean encode;
private String location;
@@ -200,7 +202,7 @@ public abstract class StrutsResultSupport implements Result, StrutsStatics {
* @throws Exception if an error occurs while executing the result.
*/
public void execute(ActionInvocation invocation) throws Exception {
lastFinalLocation = conditionalParse(location, invocation);
lastFinalLocation = parseLocation ? conditionalParse(location, invocation) : location;
doExecute(lastFinalLocation, invocation);
}
@@ -18,6 +18,9 @@
*/
package org.apache.struts2.util;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import javax.servlet.jsp.JspWriter;
import java.io.*;
import java.nio.ByteBuffer;
@@ -35,6 +38,9 @@ import java.util.LinkedList;
*
*/
public class FastByteArrayOutputStream extends OutputStream {
private static final Logger LOG = LogManager.getLogger(FastByteArrayOutputStream.class);
private static final int DEFAULT_BLOCK_SIZE = 8192;
private LinkedList<byte[]> buffers;
@@ -144,7 +150,7 @@ public class FastByteArrayOutputStream extends OutputStream {
// Append bytes to current buffer
// Previous data maybe partially decoded, this part will appended to previous
in.put(bytes, 0, length);
// To begin of data
// To begin processing of data
in.flip();
decodeAndWriteBuffered(writer, in, out, decoder, endOfInput);
}
@@ -158,7 +164,7 @@ public class FastByteArrayOutputStream extends OutputStream {
if (in.hasRemaining()) {
// Move remaining to top of buffer
in.compact();
if (result.isOverflow() && !result.isError() && !result.isMalformed()) {
if (result.isOverflow() && !result.isError()) { // isError covers isMalformed and isUnmappable
// Not all buffer chars decoded, spin it again
// Set to begin
in.flip();
@@ -167,16 +173,24 @@ public class FastByteArrayOutputStream extends OutputStream {
// Clean up buffer
in.clear();
}
} while (in.hasRemaining() && result.isOverflow() && !result.isError() && !result.isMalformed());
} while (in.hasRemaining() && result.isOverflow() && !result.isError()); // isError covers isMalformed and isUnmappable
if (result.isError()) {
if (LOG.isWarnEnabled()) {
// Provide a log warning when the decoding fails (prior to 2.5.19 it failed silently).
// Note: Set FastByteArrayOutputStream's Logger level to error or higher to suppress this log warning.
LOG.warn("Buffer decoding-in-to-out [{}] failed, coderResult [{}]", decoder.charset().name(), result.toString());
}
}
}
private static CoderResult decodeAndWrite(Writer writer, ByteBuffer in, CharBuffer out, CharsetDecoder decoder, boolean endOfInput) throws IOException {
CoderResult result = decoder.decode(in, out, endOfInput);
// To begin of decoded data
// To begin processing of decoded data
out.flip();
// Output
writer.write(out.toString());
// clear output to avoid infinitive loops, see WW-4383
// Clear output to avoid infinite loops, see WW-4383
out.clear();
return result;
}
@@ -81,7 +81,7 @@ public class JBossFileManager extends DefaultFileManager {
@Override
public void monitorFile(URL fileUrl) {
if (isJBossUrl(fileUrl)) {
if (reloadingConfigs && isJBossUrl(fileUrl)) {
String fileName = fileUrl.toString();
LOG.debug("Creating revision for URL: {}", fileName);
URL normalizedUrl = normalizeToFileProtocol(fileUrl);
@@ -35,6 +35,7 @@ public class SetTag extends ContextBeanTag {
protected String scope;
protected String value;
protected boolean trimBody = true;
public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
return new Set(stack);
@@ -59,4 +60,17 @@ public class SetTag extends ContextBeanTag {
public void setValue(String value) {
this.value = value;
}
public void setTrimBody(boolean trimBody) {
this.trimBody = trimBody;
}
@Override
protected String getBody() {
if (trimBody) {
return super.getBody();
} else {
return (bodyContent == null ? "" : bodyContent.getString());
}
}
}
@@ -36,6 +36,9 @@ public class OptGroupTag extends ComponentTagSupport {
protected String disabled;
protected String listKey;
protected String listValue;
protected String listCssClass;
protected String listCssStyle;
protected String listTitle;
public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
return new OptGroup(stack, req, res);
@@ -50,6 +53,9 @@ public class OptGroupTag extends ComponentTagSupport {
optGroup.setDisabled(disabled);
optGroup.setListKey(listKey);
optGroup.setListValue(listValue);
optGroup.setListCssClass(listCssClass);
optGroup.setListCssStyle(listCssStyle);
optGroup.setListTitle(listTitle);
}
public void setList(String list) {
@@ -71,4 +77,16 @@ public class OptGroupTag extends ComponentTagSupport {
public void setListValue(String listValue) {
this.listValue = listValue;
}
public void setListCssClass(String listCssClass) {
this.listCssClass = listCssClass;
}
public void setListCssStyle(String listCssStyle) {
this.listCssStyle = listCssStyle;
}
public void setListTitle(String listTitle) {
this.listTitle = listTitle;
}
}
+6 -10
View File
@@ -45,12 +45,6 @@
java.lang.ClassLoader,
java.lang.Shutdown,
java.lang.ProcessBuilder,
ognl.OgnlContext,
ognl.ClassResolver,
ognl.TypeConverter,
ognl.MemberAccess,
ognl.DefaultMemberAccess,
com.opensymphony.xwork2.ognl.SecurityMemberAccess,
com.opensymphony.xwork2.ActionContext" />
<!-- this must be valid regex, each '.' in package name must be escaped! -->
@@ -60,15 +54,17 @@
<!-- this is simpler version of the above used with string comparison -->
<constant name="struts.excludedPackageNames"
value="
java.lang.,
ognl.,
javax,
javax.,
freemarker.core.,
freemarker.template.,
freemarker.ext.rhino.,
freemarker.ext.beans.,
sun.reflect.,
javassist." />
javassist.,
org.objectweb.asm.,
com.opensymphony.xwork2.ognl.,
com.opensymphony.xwork2.security.,
com.opensymphony.xwork2.util." />
<bean class="com.opensymphony.xwork2.ObjectFactory" name="struts"/>
<bean type="com.opensymphony.xwork2.factory.ResultFactory" name="struts" class="org.apache.struts2.factory.StrutsResultFactory" />
@@ -21,27 +21,47 @@
<#if parameters.optGroupInternalListUiBeanList??>
<#assign optGroupInternalListUiBeans=parameters.optGroupInternalListUiBeanList />
<#list optGroupInternalListUiBeans as optGroupInternalListUiBean>
<optgroup
<optgroup<#rt>
<#if optGroupInternalListUiBean.parameters.label?has_content>
label="${optGroupInternalListUiBean.parameters.label}"
label="${optGroupInternalListUiBean.parameters.label}"<#rt>
</#if>
<#if optGroupInternalListUiBean.parameters.disabled!false>
disabled="disabled"
disabled="disabled"<#rt>
</#if>
<#include "/${parameters.templateDir}/${parameters.expandTheme}/dynamic-attributes.ftl" />
>
<#list optGroupInternalListUiBean.parameters.list as optGroupBean>
<#assign trash=stack.push(optGroupBean) />
<#assign tmpKey=stack.findValue(optGroupInternalListUiBean.parameters.listKey) />
<#assign tmpValue=stack.findValue(optGroupInternalListUiBean.parameters.listValue) />
<#assign tmpKeyStr = tmpKey.toString() />
<option value="${tmpKeyStr?html}"
<#if tag.contains(parameters.nameValue, tmpKey) == true>
selected="selected"
<#assign optGroupItemCssClass = ''/>
<#if optGroupInternalListUiBean.parameters.listCssClass??>
<#assign optGroupItemCssClass= stack.findString(optGroupInternalListUiBean.parameters.listCssClass)!''/>
</#if>
>${tmpValue?html}
</option>
<#assign optGroupItemCssStyle = ''/>
<#if optGroupInternalListUiBean.parameters.listCssStyle??>
<#assign optGroupItemCssStyle= stack.findString(optGroupInternalListUiBean.parameters.listCssStyle)!''/>
</#if>
<#assign optGroupItemTitle = ''/>
<#if optGroupInternalListUiBean.parameters.listTitle??>
<#assign optGroupItemTitle= stack.findString(optGroupInternalListUiBean.parameters.listTitle)!''/>
</#if>
<option value="${tmpKeyStr?html}"<#rt>
<#if tag.contains(parameters.nameValue, tmpKey) == true>
selected="selected"<#rt>
</#if>
<#if optGroupItemCssClass?has_content>
class="${optGroupItemCssClass?html}"<#rt/>
</#if>
<#if optGroupItemCssStyle?has_content>
style="${optGroupItemCssStyle?html}"<#rt/>
</#if>
<#if optGroupItemTitle?has_content>
title="${optGroupItemTitle?html}"<#rt/>
</#if>
>${tmpValue?html}<#t>
</option><#lt>
<#assign trash=stack.pop() />
</#list>
</optgroup>
@@ -57,6 +57,22 @@ Please do not edit it directly.
<td align="left" valign="top">String</td>
<td align="left" valign="top">Set the list attribute.</td>
</tr>
<tr>
<td align="left" valign="top">listCssClass</td>
<td align="left" valign="top">false</td>
<td align="left" valign="top"></td>
<td align="left" valign="top">false</td>
<td align="left" valign="top">String</td>
<td align="left" valign="top">Property of list objects to get css class from</td>
</tr>
<tr>
<td align="left" valign="top">listCssStyle</td>
<td align="left" valign="top">false</td>
<td align="left" valign="top"></td>
<td align="left" valign="top">false</td>
<td align="left" valign="top">String</td>
<td align="left" valign="top">Property of list objects to get css style from</td>
</tr>
<tr>
<td align="left" valign="top">listKey</td>
<td align="left" valign="top">false</td>
@@ -65,6 +81,14 @@ Please do not edit it directly.
<td align="left" valign="top">String</td>
<td align="left" valign="top">Set the listKey attribute.</td>
</tr>
<tr>
<td align="left" valign="top">listTitle</td>
<td align="left" valign="top">false</td>
<td align="left" valign="top"></td>
<td align="left" valign="top">false</td>
<td align="left" valign="top">String</td>
<td align="left" valign="top">Property of list objects to get title from</td>
</tr>
<tr>
<td align="left" valign="top">listValue</td>
<td align="left" valign="top">false</td>
+8
View File
@@ -41,6 +41,14 @@ Please do not edit it directly.
<td align="left" valign="top">String</td>
<td align="left" valign="top">The scope in which to assign the variable. Can be <b>application</b>, <b>session</b>, <b>request</b>, <b>page</b>, or <b>action</b>.</td>
</tr>
<tr>
<td align="left" valign="top">trimBody</td>
<td align="left" valign="top">false</td>
<td align="left" valign="top">true</td>
<td align="left" valign="top">false</td>
<td align="left" valign="top">Boolean</td>
<td align="left" valign="top">Set to false to prevent the default whitespace-trim of this tag's body content</td>
</tr>
<tr>
<td align="left" valign="top">value</td>
<td align="left" valign="top">false</td>
@@ -18,31 +18,45 @@
*/
package com.opensymphony.xwork2.config.providers;
import org.apache.struts2.StrutsInternalTestCase;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
import org.apache.commons.lang3.SystemUtils;
import org.apache.struts2.StrutsInternalTestCase;
public class EnvsValueSubstitutorTest extends StrutsInternalTestCase {
public void testSimpleValue() throws Exception {
// given
String expected = System.getenv("USER");
ValueSubstitutor substitutor = new EnvsValueSubstitutor();
private ValueSubstitutor substitutor;
// when
String actual = substitutor.substitute("${env.USER}");
// then
assertEquals(expected, actual);
@Override
protected void setUp() throws Exception {
super.setUp();
substitutor = new EnvsValueSubstitutor();
}
public void testNoSubstitution() throws Exception {
// given
ValueSubstitutor substitutor = new EnvsValueSubstitutor();
// when
String actual = substitutor.substitute("val1");
// then
assertEquals("val1", actual);
public void testEnvSimpleValue() {
if (SystemUtils.IS_OS_WINDOWS) {
assertThat(substitutor.substitute("${env.USERNAME}"), is(System.getenv("USERNAME")));
} else {
assertThat(substitutor.substitute("${env.USER}"), is(System.getenv("USER")));
}
}
}
public void testEnvSimpleDefaultValue() {
final String defaultValue = "defaultValue";
assertThat(substitutor.substitute("${env.UNKNOWN:" + defaultValue + "}"), is(defaultValue));
}
public void testSystemSimpleValue() {
final String key = "sysPropKey";
final String value = "sysPropValue";
System.setProperty(key, value);
assertThat(substitutor.substitute("${" + key + "}"), is(value));
}
public void testNoSubstitution() {
final String value = "val1";
assertThat(substitutor.substitute(value), is(value));
}
}
@@ -18,29 +18,42 @@
*/
package com.opensymphony.xwork2.config.providers;
import com.opensymphony.xwork2.config.ConfigurationException;
import com.opensymphony.xwork2.config.ConfigurationProvider;
import org.apache.commons.lang3.SystemUtils;
import org.apache.struts2.StrutsConstants;
public class XmlConfigurationProviderEnvsSubstitutionTest extends ConfigurationTestBase {
public void testSubstitution() throws ConfigurationException {
final String filename = "com/opensymphony/xwork2/config/providers/xwork-test-envs-substitution.xml";
ConfigurationProvider provider = buildConfigurationProvider(filename);
@Override
protected void setUp() throws Exception {
super.setUp();
configurationManager.addContainerProvider(provider);
configurationManager.addContainerProvider(buildConfigurationProvider(
"com/opensymphony/xwork2/config/providers/xwork-test-envs-substitution.xml"));
configurationManager.reload();
configuration = configurationManager.getConfiguration();
container = configuration.getContainer();
}
String foo = container.getInstance(String.class, "foo");
assertEquals("bar", foo);
public void testSubstitution() {
assertEquals("bar", container.getInstance(String.class, "foo"));
String user = container.getInstance(String.class, "user");
assertEquals(System.getenv("USER"), user);
String user;
if (SystemUtils.IS_OS_WINDOWS) {
user = container.getInstance(String.class, "username");
assertEquals(System.getenv("USERNAME"), user);
} else {
user = container.getInstance(String.class, "user");
assertEquals(System.getenv("USER"), user);
}
String home = container.getInstance(String.class, "home");
assertEquals("Current HOME = " + System.getenv("HOME"), home);
String home;
if (SystemUtils.IS_OS_WINDOWS) {
home = container.getInstance(String.class, "homedrive.homepath");
assertEquals("Current HOMEDRIVE.HOMEPATH = " + System.getenv("HOMEDRIVE") + System.getenv("HOMEPATH"), home);
} else {
home = container.getInstance(String.class, "home");
assertEquals("Current HOME = " + System.getenv("HOME"), home);
}
String os = container.getInstance(String.class, "os");
assertEquals("Current OS = " + System.getProperty("os.name"), os);
@@ -31,6 +31,9 @@ import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -78,12 +81,14 @@ public class XmlConfigurationProviderTest extends ConfigurationTestBase {
}
public void testNeedsReload() throws Exception {
container.getInstance(FileManagerFactory.class).setReloadingConfigs("true");
final String filename = "com/opensymphony/xwork2/config/providers/xwork-test-actions.xml";
ConfigurationProvider provider = buildConfigurationProvider(filename);
container.getInstance(FileManagerFactory.class).setReloadingConfigs("true");
ConfigurationProvider provider = new XmlConfigurationProvider(filename, true);
container.inject(provider);
provider.init(configuration);
provider.loadPackages();
container.getInstance(FileManagerFactory.class).getFileManager().setReloadingConfigs(true);
assertTrue(!provider.needsReload()); // Revision exists and timestamp didn't change
assertFalse(provider.needsReload()); // Revision exists and timestamp didn't change
File file = new File(getClass().getResource("/" + filename).toURI());
assertTrue("not exists: " + file.toString(), file.exists());
@@ -92,6 +97,54 @@ public class XmlConfigurationProviderTest extends ConfigurationTestBase {
assertTrue(provider.needsReload());
}
public void testReload() throws Exception {
final String filename = "com/opensymphony/xwork2/config/providers/xwork-test-reload.xml";
ConfigurationProvider provider = new XmlConfigurationProvider(filename, true);
loadConfigurationProviders(provider);
assertFalse(provider.needsReload()); // Revision exists and timestamp didn't change
File file = new File(getClass().getResource("/" + filename).toURI());
assertTrue("not exists: " + file.toString(), file.exists());
Path configPath = Paths.get(file.getAbsolutePath());
String content = new String(Files.readAllBytes(configPath));
content = content.replaceAll("<constant name=\"struts.configuration.xml.reload\" value=\"true\" />",
"<constant name=\"struts.configuration.xml.reload\" value=\"false\" />");
Files.write(configPath, content.getBytes()); // user demand: stop reloading configs
try {
assertTrue(provider.needsReload()); // config file has changed in previous lines
configurationManager.reload();
changeFileTime(file);
assertFalse(provider.needsReload()); // user already has stopped reloading configs
} finally {
content = content.replaceAll("<constant name=\"struts.configuration.xml.reload\" value=\"false\" />",
"<constant name=\"struts.configuration.xml.reload\" value=\"true\" />");
Files.write(configPath, content.getBytes());
}
}
public void testNeedsReloadNotReloadingConfigs() throws Exception {
final String filename = "com/opensymphony/xwork2/config/providers/xwork-test-actions.xml";
buildConfigurationProvider(filename);
ConfigurationProvider provider = new XmlConfigurationProvider(filename, true);
container.getInstance(FileManagerFactory.class).getFileManager().setReloadingConfigs(false);
container.inject(provider);
provider.init(configuration);
provider.loadPackages();
assertFalse(provider.needsReload()); // Revision exists and timestamp didn't change
File file = new File(getClass().getResource("/" + filename).toURI());
assertTrue("not exists: " + file.toString(), file.exists());
changeFileTime(file);
assertFalse(provider.needsReload());
}
public void testInheritence() throws Exception {
final String filename = "com/opensymphony/xwork2/config/providers/xwork-include-parent.xml";
ConfigurationProvider provider = buildConfigurationProvider(filename);
@@ -155,10 +208,13 @@ public class XmlConfigurationProviderTest extends ConfigurationTestBase {
public void testEmptySpaces() throws Exception {
final String filename = "com/opensymphony/xwork2/config/providers/xwork- test.xml";
ConfigurationProvider provider = new XmlConfigurationProvider(filename, true);
container.inject(provider);
provider.init(configuration);
provider.loadPackages();
container.getInstance(FileManagerFactory.class).getFileManager().setReloadingConfigs(true);
ConfigurationProvider provider = buildConfigurationProvider(filename);
assertTrue(!provider.needsReload());
assertFalse(provider.needsReload());
URI uri = ClassLoaderUtil.getResource(filename, ConfigurationProvider.class).toURI();
@@ -170,8 +226,28 @@ public class XmlConfigurationProviderTest extends ConfigurationTestBase {
assertTrue(provider.needsReload());
}
public void testEmptySpacesNotReloadingConfigs() throws Exception {
final String filename = "com/opensymphony/xwork2/config/providers/xwork- test.xml";
buildConfigurationProvider(filename);
ConfigurationProvider provider = new XmlConfigurationProvider(filename, true);
container.getInstance(FileManagerFactory.class).getFileManager().setReloadingConfigs(false);
container.inject(provider);
provider.init(configuration);
provider.loadPackages();
assertFalse(provider.needsReload());
URI uri = ClassLoaderUtil.getResource(filename, ConfigurationProvider.class).toURI();
File file = new File(uri);
assertTrue(file.exists());
changeFileTime(file);
assertFalse(provider.needsReload());
}
public void testConfigsInJarFiles() throws Exception {
container.getInstance(FileManagerFactory.class).getFileManager().setReloadingConfigs(true);
testProvider("xwork-jar.xml");
testProvider("xwork-zip.xml");
testProvider("xwork - jar.xml");
@@ -185,7 +261,8 @@ public class XmlConfigurationProviderTest extends ConfigurationTestBase {
private void testProvider(String configFile) throws Exception {
ConfigurationProvider provider = buildConfigurationProvider(configFile);
assertTrue(!provider.needsReload());
container.getInstance(FileManagerFactory.class).getFileManager().setReloadingConfigs(true);
assertFalse(provider.needsReload());
String fullPath = ClassLoaderUtil.getResource(configFile, ConfigurationProvider.class).toString();
@@ -197,9 +274,9 @@ public class XmlConfigurationProviderTest extends ConfigurationTestBase {
File file = new File(jar);
assertTrue("File [" + file + "] doesn't exist!", file.exists());
file.setLastModified(System.currentTimeMillis());
changeFileTime(file);
assertTrue(!provider.needsReload());
assertFalse(provider.needsReload());
}
public void testIncludeWithWildcard() throws Exception {
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
package com.opensymphony.xwork2.util;
package com.opensymphony.xwork2.conversion.impl;
import com.opensymphony.xwork2.XWorkTestCase;
@@ -0,0 +1,56 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.opensymphony.xwork2.ognl;
import org.apache.struts2.StrutsInternalTestCase;
public class OgnlUtilStrutsTest extends StrutsInternalTestCase {
private OgnlUtil ognlUtil;
@Override
public void setUp() throws Exception {
super.setUp();
ognlUtil = container.getInstance(OgnlUtil.class);
}
public void testDefaultExcludes() {
ognlUtil.setExcludedClasses("");
ognlUtil.setExcludedPackageNames("");
ognlUtil.setExcludedPackageNamePatterns("");
assertTrue(ognlUtil.getExcludedClasses().size() > 0);
assertTrue(ognlUtil.getExcludedPackageNames().size() > 0);
try {
ognlUtil.getExcludedClasses().clear();
} catch (Exception ex){
assertTrue(ex instanceof UnsupportedOperationException);
}
try {
ognlUtil.getExcludedPackageNames().clear();
} catch (Exception ex){
assertTrue(ex instanceof UnsupportedOperationException);
}
try {
ognlUtil.getExcludedPackageNamePatterns().clear();
} catch (Exception ex){
assertTrue(ex instanceof UnsupportedOperationException);
}
}
}
@@ -19,9 +19,14 @@
package com.opensymphony.xwork2.ognl;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionProxyFactory;
import com.opensymphony.xwork2.XWorkException;
import com.opensymphony.xwork2.XWorkTestCase;
import com.opensymphony.xwork2.config.ConfigurationManager;
import com.opensymphony.xwork2.config.ConfigurationProvider;
import com.opensymphony.xwork2.config.providers.XmlConfigurationProvider;
import com.opensymphony.xwork2.conversion.impl.XWorkConverter;
import com.opensymphony.xwork2.inject.Container;
import com.opensymphony.xwork2.interceptor.ChainingInterceptor;
import com.opensymphony.xwork2.test.User;
import com.opensymphony.xwork2.util.*;
@@ -29,6 +34,7 @@ import com.opensymphony.xwork2.util.reflection.ReflectionContextState;
import ognl.*;
import java.lang.reflect.Method;
import java.text.DateFormat;
import java.util.*;
public class OgnlUtilTest extends XWorkTestCase {
@@ -41,7 +47,7 @@ public class OgnlUtilTest extends XWorkTestCase {
ognlUtil = container.getInstance(OgnlUtil.class);
}
public void testCanSetADependentObject() throws Exception {
public void testCanSetADependentObject() {
String dogName = "fido";
OgnlRuntime.setNullHandler(Owner.class, new NullHandler() {
@@ -363,24 +369,19 @@ public class OgnlUtilTest extends XWorkTestCase {
Map props = new HashMap();
props.put("birthday", "02/12/1982");
// US style test
context.put(ActionContext.LOCALE, Locale.US);
ognlUtil.setProperties(props, foo, context);
Calendar cal = Calendar.getInstance();
Calendar cal = Calendar.getInstance(Locale.US);
cal.clear();
cal.set(Calendar.MONTH, Calendar.FEBRUARY);
cal.set(Calendar.DAY_OF_MONTH, 12);
cal.set(Calendar.YEAR, 1982);
assertEquals(cal.getTime(), foo.getBirthday());
//UK style test
props.put("event", "18/10/2006 14:23:45");
props.put("meeting", "09/09/2006 14:30");
context.put(ActionContext.LOCALE, Locale.UK);
ognlUtil.setProperties(props, foo, context);
cal = Calendar.getInstance();
//UK style test
cal = Calendar.getInstance(Locale.UK);
cal.clear();
cal.set(Calendar.MONTH, Calendar.OCTOBER);
cal.set(Calendar.DAY_OF_MONTH, 18);
@@ -388,24 +389,39 @@ public class OgnlUtilTest extends XWorkTestCase {
cal.set(Calendar.HOUR_OF_DAY, 14);
cal.set(Calendar.MINUTE, 23);
cal.set(Calendar.SECOND, 45);
assertEquals(cal.getTime(), foo.getEvent());
cal = Calendar.getInstance();
Date eventTime = cal.getTime();
String formatted = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM, Locale.UK)
.format(eventTime);
props.put("event", formatted);
cal = Calendar.getInstance(Locale.UK);
cal.clear();
cal.set(Calendar.MONTH, Calendar.SEPTEMBER);
cal.set(Calendar.DAY_OF_MONTH, 9);
cal.set(Calendar.YEAR, 2006);
cal.set(Calendar.HOUR_OF_DAY, 14);
cal.set(Calendar.MINUTE, 30);
assertEquals(cal.getTime(), foo.getMeeting());
Date meetingTime = cal.getTime();
formatted = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM, Locale.UK)
.format(meetingTime);
props.put("meeting", formatted);
context.put(ActionContext.LOCALE, Locale.UK);
ognlUtil.setProperties(props, foo, context);
assertEquals(eventTime, foo.getEvent());
assertEquals(meetingTime, foo.getMeeting());
//test RFC 3339 date format for JSON
props.put("event", "1996-12-19T16:39:57Z");
context.put(ActionContext.LOCALE, Locale.US);
ognlUtil.setProperties(props, foo, context);
cal = Calendar.getInstance();
cal = Calendar.getInstance(Locale.US);
cal.clear();
cal.set(Calendar.MONTH, Calendar.DECEMBER);
cal.set(Calendar.DAY_OF_MONTH, 19);
@@ -418,6 +434,7 @@ public class OgnlUtilTest extends XWorkTestCase {
//test setting a calendar property
props.put("calendar", "1996-12-19T16:39:57Z");
context.put(ActionContext.LOCALE, Locale.US);
ognlUtil.setProperties(props, foo, context);
assertEquals(cal, foo.getCalendar());
}
@@ -636,7 +653,7 @@ public class OgnlUtilTest extends XWorkTestCase {
try {
stack.setValue("1234", foo);
fail("non-valid expression: 1114778947765");
fail("non-valid expression: 1234");
}
catch(RuntimeException ex) {
;
@@ -648,6 +665,126 @@ public class OgnlUtilTest extends XWorkTestCase {
stack.setValue("1234", foo);
}
public void testStackValueDevModeChange() throws Exception {
try {
reloadTestContainerConfiguration(false, false); // Set dev mode false
}
catch (Exception ex) {
fail("Unable to reload container configuration - exception: " + ex);
}
ValueStack stack = ActionContext.getContext().getValueStack();
Map stackContext = stack.getContext();
stackContext.put(ReflectionContextState.CREATE_NULL_OBJECTS, Boolean.FALSE);
stackContext.put(ReflectionContextState.DENY_METHOD_EXECUTION, Boolean.TRUE);
stackContext.put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE);
String[] foo = new String[]{"asdf"};
// With dev mode false, the following set values should not cause failures
stack.setValue("list.1114778947765", foo);
stack.setValue("1114778947765", foo);
stack.setValue("1234", foo);
try {
reloadTestContainerConfiguration(true, false); // Set dev mode true
}
catch (Exception ex) {
fail("Unable to reload container configuration - exception: " + ex);
}
// Repeat stack/context set after retrieving updated stack
stack = ActionContext.getContext().getValueStack();
stackContext = stack.getContext();
stackContext.put(ReflectionContextState.CREATE_NULL_OBJECTS, Boolean.FALSE);
stackContext.put(ReflectionContextState.DENY_METHOD_EXECUTION, Boolean.TRUE);
stackContext.put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE);
try {
stack.setValue("list.1114778947765", foo);
fail("non-valid expression: list.1114778947765");
}
catch(RuntimeException ex) {
// Expected with dev mode true
}
try {
stack.setValue("1114778947765", foo);
fail("non-valid expression: 1114778947765");
}
catch(RuntimeException ex) {
// Expected with dev mode true
}
try {
stack.setValue("1234", foo);
fail("non-valid expression: 1234");
}
catch(RuntimeException ex) {
// Expected with dev mode true
}
}
public void testDevModeChange() throws Exception {
try {
reloadTestContainerConfiguration(false, false); // Set dev mode false
}
catch (Exception ex) {
fail("Unable to reload container configuration - exception: " + ex);
}
ValueStack stack = ActionContext.getContext().getValueStack();
Map stackContext = stack.getContext();
stackContext.put(ReflectionContextState.CREATE_NULL_OBJECTS, Boolean.FALSE);
stackContext.put(ReflectionContextState.DENY_METHOD_EXECUTION, Boolean.TRUE);
stackContext.put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE);
String[] foo = new String[]{"asdf"};
// With dev mode false, the following set values should not cause failures
stack.setValue("list.1114778947765", foo);
stack.setValue("1114778947765", foo);
stack.setValue("1234", foo);
try {
reloadTestContainerConfiguration(true, false); // Set dev mode true
}
catch (Exception ex) {
fail("Unable to reload container configuration - exception: " + ex);
}
// Repeat stack/context set after retrieving updated stack
stack = ActionContext.getContext().getValueStack();
stackContext = stack.getContext();
stackContext.put(ReflectionContextState.CREATE_NULL_OBJECTS, Boolean.FALSE);
stackContext.put(ReflectionContextState.DENY_METHOD_EXECUTION, Boolean.TRUE);
stackContext.put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE);
try {
stack.setValue("list.1114778947765", foo);
fail("non-valid expression: list.1114778947765");
}
catch(RuntimeException ex) {
// Expected with dev mode true
}
try {
stack.setValue("1114778947765", foo);
fail("non-valid expression: 1114778947765");
}
catch(RuntimeException ex) {
// Expected with dev mode true
}
try {
stack.setValue("1234", foo);
fail("non-valid expression: 1234");
}
catch(RuntimeException ex) {
// Expected with dev mode true
}
}
public void testAvoidCallingMethodsOnObjectClass() throws Exception {
Foo foo = new Foo();
@@ -803,6 +940,39 @@ public class OgnlUtilTest extends XWorkTestCase {
assertEquals(expected.getMessage(), "It isn't a simple method which can be called!");
}
private void reloadTestContainerConfiguration(boolean devMode, boolean allowStatic) throws Exception {
super.tearDown();
ConfigurationProvider configurationProvider;
if (devMode == true && allowStatic == true) {
configurationProvider = new XmlConfigurationProvider("com/opensymphony/xwork2/config/providers/xwork-test-allowstatic-devmode-true.xml", true);
}
else if (devMode == true && allowStatic == false) {
configurationProvider = new XmlConfigurationProvider("com/opensymphony/xwork2/config/providers/xwork-test-devmode-true.xml", true);
}
else if (devMode == false && allowStatic == true) {
configurationProvider = new XmlConfigurationProvider("com/opensymphony/xwork2/config/providers/xwork-test-allowstatic-true.xml", true);
}
else { // devMode, allowStatic both false
configurationProvider = new XmlConfigurationProvider("com/opensymphony/xwork2/config/providers/xwork-test-allowstatic-devmode-false.xml", true);
}
configurationManager = new ConfigurationManager(Container.DEFAULT_NAME);
configurationManager.addContainerProvider(configurationProvider);
configuration = configurationManager.getConfiguration();
container = configuration.getContainer();
container.inject(configurationProvider);
configurationProvider.init(configuration);
actionProxyFactory = container.getInstance(ActionProxyFactory.class);
// Reset the value stack
ValueStack stack = container.getInstance(ValueStackFactory.class).createValueStack();
stack.getContext().put(ActionContext.CONTAINER, container);
ActionContext.setContext(new ActionContext(stack.getContext()));
ognlUtil = container.getInstance(OgnlUtil.class);
}
public static class Email {
String address;
@@ -19,7 +19,11 @@
package com.opensymphony.xwork2.ognl;
import com.opensymphony.xwork2.*;
import com.opensymphony.xwork2.config.ConfigurationManager;
import com.opensymphony.xwork2.config.ConfigurationProvider;
import com.opensymphony.xwork2.config.providers.XmlConfigurationProvider;
import com.opensymphony.xwork2.conversion.impl.XWorkConverter;
import com.opensymphony.xwork2.inject.Container;
import com.opensymphony.xwork2.ognl.accessor.CompoundRootAccessor;
import com.opensymphony.xwork2.test.TestBean2;
import com.opensymphony.xwork2.util.*;
@@ -594,7 +598,7 @@ public class OgnlValueStackTest extends XWorkTestCase {
assertEquals("bar:123", vs.findValue("foo.bar", String.class));
}
public void testPrimitiveSettingWithInvalidValueAddsFieldErrorInDevMode() {
public void testPrimitiveSettingWithInvalidValueAddsFieldErrorInDevMode() throws Exception {
SimpleAction action = new SimpleAction();
OgnlValueStack stack = createValueStack();
stack.getContext().put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE);
@@ -613,7 +617,7 @@ public class OgnlValueStackTest extends XWorkTestCase {
assertTrue(conversionErrors.containsKey("bar"));
}
public void testPrimitiveSettingWithInvalidValueAddsFieldErrorInNonDevMode() {
public void testPrimitiveSettingWithInvalidValueAddsFieldErrorInNonDevMode() throws Exception {
SimpleAction action = new SimpleAction();
OgnlValueStack stack = createValueStack();
stack.getContext().put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE);
@@ -968,6 +972,39 @@ public class OgnlValueStackTest extends XWorkTestCase {
assertEquals(null, stack.findValue("address.country.name", String.class));
}
private void reloadTestContainerConfiguration(boolean devMode, boolean allowStatic) throws Exception {
super.tearDown();
ConfigurationProvider configurationProvider;
if (devMode == true && allowStatic == true) {
configurationProvider = new XmlConfigurationProvider("com/opensymphony/xwork2/config/providers/xwork-test-allowstatic-devmode-true.xml", true);
}
else if (devMode == true && allowStatic == false) {
configurationProvider = new XmlConfigurationProvider("com/opensymphony/xwork2/config/providers/xwork-test-devmode-true.xml", true);
}
else if (devMode == false && allowStatic == true) {
configurationProvider = new XmlConfigurationProvider("com/opensymphony/xwork2/config/providers/xwork-test-allowstatic-true.xml", true);
}
else { // devMode, allowStatic both false
configurationProvider = new XmlConfigurationProvider("com/opensymphony/xwork2/config/providers/xwork-test-allowstatic-devmode-false.xml", true);
}
configurationManager = new ConfigurationManager(Container.DEFAULT_NAME);
configurationManager.addContainerProvider(configurationProvider);
configuration = configurationManager.getConfiguration();
container = configuration.getContainer();
container.inject(configurationProvider);
configurationProvider.init(configuration);
actionProxyFactory = container.getInstance(ActionProxyFactory.class);
// Reset the value stack
ValueStack stack = container.getInstance(ValueStackFactory.class).createValueStack();
stack.getContext().put(ActionContext.CONTAINER, container);
ActionContext.setContext(new ActionContext(stack.getContext()));
ognlUtil = container.getInstance(OgnlUtil.class);
}
class BadJavaBean {
private int count;
private int count2;
@@ -22,7 +22,6 @@ import com.opensymphony.xwork2.util.TextParseUtil;
import junit.framework.TestCase;
import java.lang.reflect.Member;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -62,7 +61,7 @@ public class SecurityMemberAccessTest extends TestCase {
String propertyName = "stringField";
Member member = FooBar.class.getDeclaredMethod("get" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1));
Set<Class<?>> excluded = new HashSet<Class<?>>();
Set<Class<?>> excluded = new HashSet<>();
excluded.add(FooBar.class);
sma.setExcludedClasses(excluded);
@@ -108,7 +107,7 @@ public class SecurityMemberAccessTest extends TestCase {
String propertyName = "barLogic";
Member member = BarInterface.class.getMethod(propertyName);
Set<Class<?>> excluded = new HashSet<Class<?>>();
Set<Class<?>> excluded = new HashSet<>();
excluded.add(BarInterface.class);
sma.setExcludedClasses(excluded);
@@ -126,7 +125,7 @@ public class SecurityMemberAccessTest extends TestCase {
String propertyName = "fooLogic";
Member member = FooBar.class.getMethod(propertyName);
Set<Class<?>> excluded = new HashSet<Class<?>>();
Set<Class<?>> excluded = new HashSet<>();
excluded.add(BarInterface.class);
sma.setExcludedClasses(excluded);
@@ -158,7 +157,7 @@ public class SecurityMemberAccessTest extends TestCase {
String propertyName = "barLogic";
Member member = BarInterface.class.getMethod(propertyName);
Set<Class<?>> excluded = new HashSet<Class<?>>();
Set<Class<?>> excluded = new HashSet<>();
excluded.add(FooBarInterface.class);
sma.setExcludedClasses(excluded);
@@ -173,7 +172,7 @@ public class SecurityMemberAccessTest extends TestCase {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(false);
Set<Pattern> excluded = new HashSet<Pattern>();
Set<Pattern> excluded = new HashSet<>();
excluded.add(Pattern.compile("^" + FooBar.class.getPackage().getName().replaceAll("\\.", "\\\\.") + ".*"));
sma.setExcludedPackageNamePatterns(excluded);
@@ -191,7 +190,7 @@ public class SecurityMemberAccessTest extends TestCase {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(false);
Set<String> excluded = new HashSet<String>();
Set<String> excluded = new HashSet<>();
excluded.add(FooBar.class.getPackage().getName());
sma.setExcludedPackageNames(excluded);
@@ -205,11 +204,11 @@ public class SecurityMemberAccessTest extends TestCase {
assertFalse("stringField is accessible!", actual);
}
public void testDefaultPackageExclusion() throws Exception {
public void testDefaultPackageExclusion() {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(false);
Set<Pattern> excluded = new HashSet<Pattern>();
Set<Pattern> excluded = new HashSet<>();
excluded.add(Pattern.compile("^" + FooBar.class.getPackage().getName().replaceAll("\\.", "\\\\.") + ".*"));
sma.setExcludedPackageNamePatterns(excluded);
@@ -220,11 +219,11 @@ public class SecurityMemberAccessTest extends TestCase {
assertFalse("default package is excluded!", actual);
}
public void testDefaultPackageExclusion2() throws Exception {
public void testDefaultPackageExclusion2() {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(false);
Set<Pattern> excluded = new HashSet<Pattern>();
Set<Pattern> excluded = new HashSet<>();
excluded.add(Pattern.compile("^$"));
sma.setExcludedPackageNamePatterns(excluded);
@@ -317,10 +316,10 @@ public class SecurityMemberAccessTest extends TestCase {
public void testAccessPrimitiveDoubleWithNames() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(false);
sma.setExcludedPackageNames(TextParseUtil.commaDelimitedStringToSet("java.lang.,ognl,javax"));
sma.setExcludedPackageNames(TextParseUtil.commaDelimitedStringToSet("ognl.,javax."));
Set<Class<?>> excluded = new HashSet<Class<?>>();
Set<Class<?>> excluded = new HashSet<>();
excluded.add(Object.class);
excluded.add(Runtime.class);
excluded.add(System.class);
@@ -369,7 +368,7 @@ public class SecurityMemberAccessTest extends TestCase {
public void testAccessPrimitiveDoubleWithPackageRegExs() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(false);
Set<Pattern> patterns = new HashSet<Pattern>();
Set<Pattern> patterns = new HashSet<>();
patterns.add(Pattern.compile("^java\\.lang\\..*"));
sma.setExcludedPackageNamePatterns(patterns);
@@ -386,7 +385,7 @@ public class SecurityMemberAccessTest extends TestCase {
public void testAccessMemberAccessIsAccessible() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(false);
Set<Class<?>> excluded = new HashSet<Class<?>>();
Set<Class<?>> excluded = new HashSet<>();
excluded.add(ognl.MemberAccess.class);
sma.setExcludedClasses(excluded);
@@ -404,7 +403,7 @@ public class SecurityMemberAccessTest extends TestCase {
public void testAccessMemberAccessIsBlocked() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(false);
Set<Class<?>> excluded = new HashSet<Class<?>>();
Set<Class<?>> excluded = new HashSet<>();
excluded.add(SecurityMemberAccess.class);
sma.setExcludedClasses(excluded);
@@ -419,6 +418,21 @@ public class SecurityMemberAccessTest extends TestCase {
assertFalse(accessible);
}
public void testPackageNameExclusionAsCommaDelimited() {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(false);
sma.setExcludedPackageNames(TextParseUtil.commaDelimitedStringToSet("java.lang."));
// when
boolean actual = sma.isPackageExcluded(String.class.getPackage(), null);
actual &= sma.isPackageExcluded(null, String.class.getPackage());
// then
assertTrue("package java.lang. is accessible!", actual);
}
}
class FooBar implements FooBarInterface {
@@ -19,11 +19,17 @@
package com.opensymphony.xwork2.util;
import com.opensymphony.xwork2.XWorkTestCase;
import org.apache.commons.io.IOUtils;
import java.io.IOException;
import java.net.URL;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;
public class ClassPathFinderTest extends XWorkTestCase {
public void testFinder() {
ClassPathFinder finder = new ClassPathFinder();
finder.setPattern("**/xwork-test-wildcard-*.xml");
@@ -52,4 +58,50 @@ public class ClassPathFinderTest extends XWorkTestCase {
}
public void testFinderNotURLClassLoader() throws Exception {
NotURLClassLoader loader = new NotURLClassLoader(Thread.currentThread().getContextClassLoader());
Thread.currentThread().setContextClassLoader(loader);
try {
Class<?> clazz = loader.loadClass(ClassPathFinderTest.class.getName());
Object test = clazz.getConstructor().newInstance();
clazz.getMethod("testFinder").invoke(test);
} finally {
Thread.currentThread().setContextClassLoader(loader.parentClassLoader);
}
}
private class NotURLClassLoader extends ClassLoader {
private Map<String, Class<?>> loadedClasses = new HashMap<>();
private ClassLoader parentClassLoader;
NotURLClassLoader(ClassLoader parentClassLoader) {
super(null);
this.parentClassLoader = parentClassLoader;
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
if (!loadedClasses.containsKey(name)) {
try {
byte[] classBits = IOUtils.toByteArray(ClassLoader.getSystemResourceAsStream(
name.replace('.', '/') + ".class"));
loadedClasses.put(name, defineClass(name, classBits, 0, classBits.length));
} catch (IOException e) {
throw new ClassNotFoundException("class " + name + " is not findable", e);
} catch (Exception e) {
loadedClasses.put(name, parentClassLoader.loadClass(name));
}
}
return loadedClasses.get(name);
}
@Override
protected Enumeration<URL> findResources(String name) throws IOException {
return parentClassLoader.getResources(name);
}
}
}
@@ -21,16 +21,9 @@ package com.opensymphony.xwork2.util;
import com.opensymphony.xwork2.FileManager;
import com.opensymphony.xwork2.FileManagerFactory;
import com.opensymphony.xwork2.XWorkTestCase;
import com.opensymphony.xwork2.util.fs.DefaultFileManager;
import org.apache.struts2.util.fs.JBossFileManager;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
import java.net.URLStreamHandlerFactory;
import java.net.*;
/**
* FileManager Tester.
@@ -49,23 +42,40 @@ public class DefaultFileManagerTest extends XWorkTestCase {
fileManager = container.getInstance(FileManagerFactory.class).getFileManager();
}
public void disabled_testGetFileInJar() throws Exception {
testLoadFile("xwork-jar.xml");
testLoadFile("xwork - jar.xml");
testLoadFile("xwork-zip.xml");
testLoadFile("xwork - zip.xml");
testLoadFile("xwork-jar2.xml");
testLoadFile("xwork - jar2.xml");
testLoadFile("xwork-zip2.xml");
testLoadFile("xwork - zip2.xml");
public void testGetFileInJar() throws Exception {
testLoadFile("xwork-jar.xml", false);
testLoadFile("xwork - jar.xml", false);
testLoadFile("xwork-zip.xml", false);
testLoadFile("xwork - zip.xml", false);
testLoadFile("xwork-jar2.xml", false);
testLoadFile("xwork - jar2.xml", false);
testLoadFile("xwork-zip2.xml", false);
testLoadFile("xwork - zip2.xml", false);
testLoadFile("xwork-jar.xml", true);
testLoadFile("xwork - jar.xml", true);
testLoadFile("xwork-zip.xml", true);
testLoadFile("xwork - zip.xml", true);
testLoadFile("xwork-jar2.xml", true);
testLoadFile("xwork - jar2.xml", true);
testLoadFile("xwork-zip2.xml", true);
testLoadFile("xwork - zip2.xml", true);
}
private void testLoadFile(String fileName) {
fileManager.setReloadingConfigs(true);
private void testLoadFile(String fileName, boolean reloadConfigs) throws Exception {
fileManager.setReloadingConfigs(reloadConfigs);
URL url = ClassLoaderUtil.getResource(fileName, DefaultFileManagerTest.class);
InputStream file = fileManager.loadFile(url);
assertNotNull(file);
assertTrue(fileManager.fileNeedsReloading(fileName));
file.close();
assertFalse(fileManager.fileNeedsReloading(url.toString()));
long now = System.currentTimeMillis();
JarURLConnection conn = (JarURLConnection) url.openConnection();
conn.getJarEntry().setTime(now + 60000);
conn.getInputStream().close();
assertEquals(reloadConfigs, fileManager.fileNeedsReloading(url.toString()));
}
public void testReloadingConfigs() throws Exception {
@@ -21,7 +21,9 @@ package com.opensymphony.xwork2.util.fs;
import com.opensymphony.xwork2.FileManager;
import com.opensymphony.xwork2.FileManagerFactory;
import com.opensymphony.xwork2.XWorkTestCase;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.filefilter.WildcardFileFilter;
import java.io.File;
import java.io.FileOutputStream;
@@ -30,6 +32,9 @@ import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.jar.Attributes;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
@@ -45,10 +50,13 @@ public class JarEntryRevisionTest extends XWorkTestCase {
fileManager = container.getInstance(FileManagerFactory.class).getFileManager();
}
private void createJarFile(long time) throws Exception {
private String createJarFile(long time) throws Exception {
Manifest manifest = new Manifest();
manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
FileOutputStream fos = new FileOutputStream("target/JarEntryRevisionTest_testNeedsReloading.jar", false);
Path jarPath = Paths.get(Thread.currentThread().getContextClassLoader()
.getResource("xwork-jar.jar").toURI()).getParent();
File jarFile = jarPath.resolve("JarEntryRevisionTest_testNeedsReloading.jar").toFile();
FileOutputStream fos = new FileOutputStream(jarFile, false);
JarOutputStream target = new JarOutputStream(fos, manifest);
target.putNextEntry(new ZipEntry("com/opensymphony/xwork2/util/fs/"));
ZipEntry entry = new ZipEntry("com/opensymphony/xwork2/util/fs/JarEntryRevisionTest.class");
@@ -60,13 +68,14 @@ public class JarEntryRevisionTest extends XWorkTestCase {
target.closeEntry();
target.close();
fos.close();
return jarFile.toURI().toURL().toExternalForm();
}
public void testNeedsReloading() throws Exception {
long now = System.currentTimeMillis();
createJarFile(now);
URL url = new URL("jar:file:target/JarEntryRevisionTest_testNeedsReloading.jar!/com/opensymphony/xwork2/util/fs/JarEntryRevisionTest.class");
URL url = new URL("jar:" + createJarFile(now) + "!/com/opensymphony/xwork2/util/fs/JarEntryRevisionTest.class");
Revision entry = JarEntryRevision.build(url, fileManager);
assert entry != null;
assertFalse(entry.needsReloading());
@@ -78,9 +87,8 @@ public class JarEntryRevisionTest extends XWorkTestCase {
public void testNeedsReloadingWithContainerProvidedURLConnection() throws Exception {
long now = System.currentTimeMillis();
createJarFile(now);
URL url = new URL(null,
"jar:file:target/JarEntryRevisionTest_testNeedsReloading.jar!/com/opensymphony/xwork2/util/fs/JarEntryRevisionTest.class",
"jar:" + createJarFile(now) + "!/com/opensymphony/xwork2/util/fs/JarEntryRevisionTest.class",
new ContainerProvidedURLStreamHandler());
Revision entry = JarEntryRevision.build(url, fileManager);
assert entry != null;
@@ -93,9 +101,7 @@ public class JarEntryRevisionTest extends XWorkTestCase {
public void testNeedsReloadingWithContainerProvidedURLConnectionEmptyProtocol() throws Exception {
long now = System.currentTimeMillis();
createJarFile(now);
File targetDir = new File("target");
String targetUrlStr = targetDir.toURI().toURL().toString();
String targetUrlStr = createJarFile(now);
if (targetUrlStr.startsWith("file:")) {
targetUrlStr = targetUrlStr.substring(5);//emptying protocol; we expect framework will fix it
}
@@ -103,7 +109,7 @@ public class JarEntryRevisionTest extends XWorkTestCase {
targetUrlStr = targetUrlStr.substring(1);//we expect framework will fix it also
}
URL url = new URL(null,
"zip:" + targetUrlStr + "JarEntryRevisionTest_testNeedsReloading.jar!/com/opensymphony/xwork2/util/fs/JarEntryRevisionTest.class",
"zip:" + targetUrlStr + "!/com/opensymphony/xwork2/util/fs/JarEntryRevisionTest.class",
new ContainerProvidedURLStreamHandler());
Revision entry = JarEntryRevision.build(url, fileManager);
assert entry != null;
@@ -113,6 +119,20 @@ public class JarEntryRevisionTest extends XWorkTestCase {
assertTrue(entry.needsReloading());
}
@Override
protected void tearDown() throws Exception {
Path tmpFile = Files.createTempFile("jar_cache", null);
Path tmpFolder = tmpFile.getParent();
int count = FileUtils.listFiles(tmpFolder.toFile(), new WildcardFileFilter("jar_cache*"),
null).size();
if (tmpFile.toFile().delete()) {
count--;
}
assertEquals(0, count);
super.tearDown();
}
/**
* WW-4901 Simulating container implementation of {@link URL#openConnection()}
@@ -20,6 +20,7 @@ package org.apache.struts2;
import java.io.InputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.StringTokenizer;
/**
@@ -27,12 +27,12 @@ import com.opensymphony.xwork2.config.entities.PackageConfig;
import com.opensymphony.xwork2.config.impl.DefaultConfiguration;
import com.opensymphony.xwork2.inject.Container;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.StrutsException;
import org.apache.struts2.StrutsInternalTestCase;
import org.apache.struts2.result.StrutsResultSupport;
import org.apache.struts2.views.jsp.StrutsMockHttpServletRequest;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@@ -65,7 +65,7 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
};
}
public void testGetMapping() throws Exception {
public void testGetMapping() {
req.setupGetRequestURI("/my/namespace/actionName.action");
req.setupGetServletPath("/my/namespace/actionName.action");
req.setupGetAttribute(null);
@@ -79,7 +79,7 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertNull(mapping.getMethod());
}
public void testGetMappingWithMethod() throws Exception {
public void testGetMappingWithMethod() {
req.setupGetParameterMap(new HashMap());
req.setupGetRequestURI("/my/namespace/actionName!add.action");
req.setupGetServletPath("/my/namespace/actionName!add.action");
@@ -95,7 +95,7 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertEquals("add", mapping.getMethod());
}
public void testGetMappingWithSlashedName() throws Exception {
public void testGetMappingWithSlashedName() {
req.setupGetRequestURI("/my/foo/actionName.action");
req.setupGetServletPath("/my/foo/actionName.action");
@@ -111,7 +111,7 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertNull(mapping.getMethod());
}
public void testGetMappingWithSlashedNameAtRootButNoSlashPackage() throws Exception {
public void testGetMappingWithSlashedNameAtRootButNoSlashPackage() {
req.setupGetRequestURI("/foo/actionName.action");
req.setupGetServletPath("/foo/actionName.action");
@@ -127,7 +127,7 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertNull(mapping.getMethod());
}
public void testGetMappingWithSlashedNameAtRoot() throws Exception {
public void testGetMappingWithSlashedNameAtRoot() {
config = new DefaultConfiguration();
PackageConfig pkg = new PackageConfig.Builder("myns")
.namespace("/my/namespace").build();
@@ -158,7 +158,7 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
public void testGetMappingWithNamespaceSlash() throws Exception {
public void testGetMappingWithNamespaceSlash() {
req.setupGetRequestURI("/my-hh/abc.action");
req.setupGetServletPath("/my-hh/abc.action");
@@ -181,7 +181,7 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertEquals("my-hh/abc", mapping.getName());
}
public void testGetMappingWithUnknownNamespace() throws Exception {
public void testGetMappingWithUnknownNamespace() {
req.setupGetRequestURI("/bo/foo/actionName.action");
req.setupGetServletPath("/bo/foo/actionName.action");
req.setupGetAttribute(null);
@@ -195,7 +195,7 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertNull(mapping.getMethod());
}
public void testGetMappingWithUnknownNamespaceButFullNamespaceSelect() throws Exception {
public void testGetMappingWithUnknownNamespaceButFullNamespaceSelect() {
req.setupGetRequestURI("/bo/foo/actionName.action");
req.setupGetServletPath("/bo/foo/actionName.action");
req.setupGetAttribute(null);
@@ -210,7 +210,7 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertNull(mapping.getMethod());
}
public void testGetMappingWithActionName_methodAndName() throws Exception {
public void testGetMappingWithActionName_methodAndName() {
DefaultActionMapper mapper = new DefaultActionMapper();
mapper.setAllowDynamicMethodCalls("true");
ActionMapping mapping = mapper.getMappingFromActionName("actionName!add");
@@ -218,24 +218,24 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertEquals("add", mapping.getMethod());
}
public void testGetMappingWithActionName_name() throws Exception {
public void testGetMappingWithActionName_name() {
DefaultActionMapper mapper = new DefaultActionMapper();
ActionMapping mapping = mapper.getMappingFromActionName("actionName");
assertEquals("actionName", mapping.getName());
assertEquals(null, mapping.getMethod());
assertNull(mapping.getMethod());
}
public void testGetMappingWithActionName_noDynamicMethod() throws Exception {
public void testGetMappingWithActionName_noDynamicMethod() {
DefaultActionMapper mapper = new DefaultActionMapper();
mapper.setAllowDynamicMethodCalls("false");
ActionMapping mapping = mapper.getMappingFromActionName("actionName!add");
assertEquals("actionName!add", mapping.getName());
assertEquals(null, mapping.getMethod());
assertNull(mapping.getMethod());
}
public void testGetMappingWithActionName_noDynamicMethodColonPrefix() throws Exception {
public void testGetMappingWithActionName_noDynamicMethodColonPrefix() {
Map parameterMap = new HashMap();
Map<String, Object> parameterMap = new HashMap<>();
parameterMap.put(DefaultActionMapper.METHOD_PREFIX + "someMethod", "");
StrutsMockHttpServletRequest request = new StrutsMockHttpServletRequest();
@@ -247,16 +247,16 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
ActionMapping actionMapping = defaultActionMapper.getMapping(request, configManager);
assertEquals("someServletPath", actionMapping.getName());
assertEquals(null, actionMapping.getMethod());
assertNull(actionMapping.getMethod());
}
public void testGetMappingWithActionName_null() throws Exception {
public void testGetMappingWithActionName_null() {
DefaultActionMapper mapper = new DefaultActionMapper();
ActionMapping mapping = mapper.getMappingFromActionName(null);
assertNull(mapping);
}
public void testGetUri() throws Exception {
public void testGetUri() {
req.setupGetParameterMap(new HashMap());
req.setupGetRequestURI("/my/namespace/actionName.action");
req.setupGetServletPath("/my/namespace/actionName.action");
@@ -268,7 +268,7 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertEquals("/my/namespace/actionName.action", mapper.getUriFromActionMapping(mapping));
}
public void testGetUriWithSemicolonPresent() throws Exception {
public void testGetUriWithSemicolonPresent() {
req.setupGetParameterMap(new HashMap());
req.setupGetRequestURI("/my/namespace/actionName.action;abc=123rty56");
req.setupGetServletPath("/my/namespace/actionName.action;abc=123rty56");
@@ -280,7 +280,7 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertEquals("/my/namespace/actionName.action", mapper.getUriFromActionMapping(mapping));
}
public void testGetUriWithMethod() throws Exception {
public void testGetUriWithMethod() {
req.setupGetParameterMap(new HashMap());
req.setupGetRequestURI("/my/namespace/actionName!add.action");
req.setupGetServletPath("/my/namespace/actionName!add.action");
@@ -293,8 +293,8 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertEquals("/my/namespace/actionName!add.action", mapper.getUriFromActionMapping(mapping));
}
public void testGetUriWithOriginalExtension() throws Exception {
ActionMapping mapping = new ActionMapping("actionName", "/ns", null, new HashMap());
public void testGetUriWithOriginalExtension() {
ActionMapping mapping = new ActionMapping("actionName", "/ns", null, new HashMap<String, Object>());
ActionMapping orig = new ActionMapping();
orig.setExtension("foo");
@@ -304,7 +304,7 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertEquals("/ns/actionName.foo", mapper.getUriFromActionMapping(mapping));
}
public void testGetMappingWithNoExtension() throws Exception {
public void testGetMappingWithNoExtension() {
req.setupGetParameterMap(new HashMap());
req.setupGetRequestURI("/my/namespace/actionName");
req.setupGetServletPath("/my/namespace/actionName");
@@ -320,7 +320,7 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertNull(mapping.getMethod());
}
public void testGetMappingWithNoExtensionButUriHasExtension() throws Exception {
public void testGetMappingWithNoExtensionButUriHasExtension() {
req.setupGetParameterMap(new HashMap());
req.setupGetRequestURI("/my/namespace/actionName.html");
req.setupGetServletPath("/my/namespace/actionName.html");
@@ -340,7 +340,7 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
// === test name & namespace ===
// =============================
public void testParseNameAndNamespace1() throws Exception {
public void testParseNameAndNamespace1() {
ActionMapping actionMapping = new ActionMapping();
DefaultActionMapper defaultActionMapper = new DefaultActionMapper();
@@ -350,7 +350,7 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertEquals(actionMapping.getNamespace(), "");
}
public void testParseNameAndNamespace2() throws Exception {
public void testParseNameAndNamespace2() {
ActionMapping actionMapping = new ActionMapping();
DefaultActionMapper defaultActionMapper = new DefaultActionMapper();
@@ -360,7 +360,7 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertEquals(actionMapping.getNamespace(), "/");
}
public void testParseNameAndNamespace3() throws Exception {
public void testParseNameAndNamespace3() {
ActionMapping actionMapping = new ActionMapping();
DefaultActionMapper defaultActionMapper = new DefaultActionMapper();
@@ -370,7 +370,7 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertEquals(actionMapping.getNamespace(), "/my");
}
public void testParseNameAndNamespace_NoSlashes() throws Exception {
public void testParseNameAndNamespace_NoSlashes() {
ActionMapping actionMapping = new ActionMapping();
DefaultActionMapper defaultActionMapper = new DefaultActionMapper();
@@ -381,7 +381,7 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertEquals(actionMapping.getNamespace(), "");
}
public void testParseNameAndNamespace_AllowSlashes() throws Exception {
public void testParseNameAndNamespace_AllowSlashes() {
ActionMapping actionMapping = new ActionMapping();
DefaultActionMapper defaultActionMapper = new DefaultActionMapper();
@@ -397,8 +397,8 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
// === test special prefix ===
// ===========================
public void testActionPrefixWhenDisabled() throws Exception {
Map parameterMap = new HashMap();
public void testActionPrefixWhenDisabled() {
Map<String, Object> parameterMap = new HashMap<>();
parameterMap.put(DefaultActionMapper.ACTION_PREFIX + "myAction", "");
StrutsMockHttpServletRequest request = new StrutsMockHttpServletRequest();
@@ -411,8 +411,8 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertEquals("someServletPath", actionMapping.getName());
}
public void testActionPrefixWhenEnabled() throws Exception {
Map parameterMap = new HashMap();
public void testActionPrefixWhenEnabled() {
Map<String, Object> parameterMap = new HashMap<>();
parameterMap.put(DefaultActionMapper.ACTION_PREFIX + "myAction", "");
StrutsMockHttpServletRequest request = new StrutsMockHttpServletRequest();
@@ -426,8 +426,8 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertEquals("myAction", actionMapping.getName());
}
public void testActionPrefixWhenSlashesAndCrossNamespaceDisabled() throws Exception {
Map parameterMap = new HashMap();
public void testActionPrefixWhenSlashesAndCrossNamespaceDisabled() {
Map<String, Object> parameterMap = new HashMap<>();
parameterMap.put(DefaultActionMapper.ACTION_PREFIX + "my/Action", "");
StrutsMockHttpServletRequest request = new StrutsMockHttpServletRequest();
@@ -442,8 +442,8 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertEquals("my/Action", actionMapping.getName());
}
public void testActionPrefixWhenSlashesButSlashesDisabledAndCrossNamespaceDisabled() throws Exception {
Map parameterMap = new HashMap();
public void testActionPrefixWhenSlashesButSlashesDisabledAndCrossNamespaceDisabled() {
Map<String, Object> parameterMap = new HashMap<>();
parameterMap.put(DefaultActionMapper.ACTION_PREFIX + "my/Action", "");
StrutsMockHttpServletRequest request = new StrutsMockHttpServletRequest();
@@ -458,8 +458,8 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertEquals("Action", actionMapping.getName());
}
public void testActionPrefixWhenSlashesButSlashesDisabledAndCrossNamespace() throws Exception {
Map parameterMap = new HashMap();
public void testActionPrefixWhenSlashesButSlashesDisabledAndCrossNamespace() {
Map<String, Object> parameterMap = new HashMap<>();
parameterMap.put(DefaultActionMapper.ACTION_PREFIX + "my/Action", "");
StrutsMockHttpServletRequest request = new StrutsMockHttpServletRequest();
@@ -475,8 +475,8 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertEquals("my/Action", actionMapping.getName());
}
public void testActionPrefixWhenCrossNamespace() throws Exception {
Map parameterMap = new HashMap();
public void testActionPrefixWhenCrossNamespace() {
Map<String, Object> parameterMap = new HashMap<>();
parameterMap.put(DefaultActionMapper.ACTION_PREFIX + "/my/Action", "");
StrutsMockHttpServletRequest request = new StrutsMockHttpServletRequest();
@@ -491,8 +491,8 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertEquals("/my/Action", actionMapping.getName());
}
public void testActionPrefix_fromImageButton() throws Exception {
Map parameterMap = new HashMap();
public void testActionPrefix_fromImageButton() {
Map<String, Object> parameterMap = new HashMap<>();
parameterMap.put(DefaultActionMapper.ACTION_PREFIX + "myAction", "");
parameterMap.put(DefaultActionMapper.ACTION_PREFIX + "myAction.x", "");
parameterMap.put(DefaultActionMapper.ACTION_PREFIX + "myAction.y", "");
@@ -508,8 +508,8 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertEquals("myAction", actionMapping.getName());
}
public void testActionPrefix_fromIEImageButton() throws Exception {
Map parameterMap = new HashMap();
public void testActionPrefix_fromIEImageButton() {
Map<String, Object> parameterMap = new HashMap<>();
parameterMap.put(DefaultActionMapper.ACTION_PREFIX + "myAction.x", "");
parameterMap.put(DefaultActionMapper.ACTION_PREFIX + "myAction.y", "");
@@ -524,8 +524,8 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertEquals("myAction", actionMapping.getName());
}
public void testRedirectPrefix() throws Exception {
Map parameterMap = new HashMap();
public void testRedirectPrefix() {
Map<String, Object> parameterMap = new HashMap<>();
parameterMap.put("redirect:" + "http://www.google.com", "");
StrutsMockHttpServletRequest request = new StrutsMockHttpServletRequest();
@@ -540,8 +540,8 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertNull(result);
}
public void testUnsafeRedirectPrefix() throws Exception {
Map parameterMap = new HashMap();
public void testUnsafeRedirectPrefix() {
Map<String, Object> parameterMap = new HashMap<>();
parameterMap.put("redirect:" + "http://%{3*4}", "");
StrutsMockHttpServletRequest request = new StrutsMockHttpServletRequest();
@@ -556,8 +556,8 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertNull(result);
}
public void testRedirectActionPrefix() throws Exception {
Map parameterMap = new HashMap();
public void testRedirectActionPrefix() {
Map<String, Object> parameterMap = new HashMap<>();
parameterMap.put("redirectAction:" + "myAction", "");
StrutsMockHttpServletRequest request = new StrutsMockHttpServletRequest();
@@ -573,8 +573,8 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertNull(result);
}
public void testUnsafeRedirectActionPrefix() throws Exception {
Map parameterMap = new HashMap();
public void testUnsafeRedirectActionPrefix() {
Map<String, Object> parameterMap = new HashMap<>();
parameterMap.put("redirectAction:" + "%{3*4}", "");
StrutsMockHttpServletRequest request = new StrutsMockHttpServletRequest();
@@ -590,8 +590,8 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertNull(result);
}
public void testRedirectActionPrefixWithEmptyExtension() throws Exception {
Map parameterMap = new HashMap();
public void testRedirectActionPrefixWithEmptyExtension() {
Map<String, Object> parameterMap = new HashMap<>();
parameterMap.put("redirectAction:" + "myAction", "");
StrutsMockHttpServletRequest request = new StrutsMockHttpServletRequest();
@@ -608,8 +608,8 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertNull(result);
}
public void testCustomActionPrefix() throws Exception {
Map parameterMap = new HashMap();
public void testCustomActionPrefix() {
Map<String, Object> parameterMap = new HashMap<>();
parameterMap.put("foo:myAction", "");
final StrutsMockHttpServletRequest request = new StrutsMockHttpServletRequest();
@@ -627,39 +627,39 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertEquals(actionMapping.getName(), "myAction");
}
public void testDropExtension() throws Exception {
public void testDropExtension() {
DefaultActionMapper mapper = new DefaultActionMapper();
String name = mapper.dropExtension("foo.action", new ActionMapping());
assertTrue("Name not right: "+name, "foo".equals(name));
assertEquals("Name not right: " + name, "foo", name);
name = mapper.dropExtension("foo.action.action", new ActionMapping());
assertTrue("Name not right: "+name, "foo.action".equals(name));
assertEquals("Name not right: " + name, "foo.action", name);
}
public void testDropExtensionWhenBlank() throws Exception {
public void testDropExtensionWhenBlank() {
DefaultActionMapper mapper = new DefaultActionMapper();
mapper.setExtensions("action,,");
String name = mapper.dropExtension("foo.action", new ActionMapping());
assertTrue("Name not right: "+name, "foo".equals(name));
assertEquals("Name not right: " + name, "foo", name);
name = mapper.dropExtension("foo", new ActionMapping());
assertTrue("Name not right: "+name, "foo".equals(name));
assertEquals("Name not right: " + name, "foo", name);
assertNull(mapper.dropExtension("foo.bar", new ActionMapping()));
assertNull(mapper.dropExtension("foo.", new ActionMapping()));
}
public void testDropExtensionEmbeddedDot() throws Exception {
public void testDropExtensionEmbeddedDot() {
DefaultActionMapper mapper = new DefaultActionMapper();
mapper.setExtensions("action,,");
String name = mapper.dropExtension("/foo/bar-1.0/baz.action", new ActionMapping());
assertTrue("Name not right: "+name, "/foo/bar-1.0/baz".equals(name));
assertEquals("Name not right: " + name, "/foo/bar-1.0/baz", name);
name = mapper.dropExtension("/foo/bar-1.0/baz", new ActionMapping());
assertTrue("Name not right: "+name, "/foo/bar-1.0/baz".equals(name));
assertEquals("Name not right: " + name, "/foo/bar-1.0/baz", name);
}
public void testGetUriFromActionMapper1() throws Exception {
public void testGetUriFromActionMapper1() {
DefaultActionMapper mapper = new DefaultActionMapper();
ActionMapping actionMapping = new ActionMapping();
actionMapping.setMethod("myMethod");
@@ -670,7 +670,7 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertEquals("/myNamespace/myActionName!myMethod.action", uri);
}
public void testGetUriFromActionMapper2() throws Exception {
public void testGetUriFromActionMapper2() {
DefaultActionMapper mapper = new DefaultActionMapper();
ActionMapping actionMapping = new ActionMapping();
actionMapping.setMethod("myMethod");
@@ -681,7 +681,7 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertEquals("/myActionName!myMethod.action", uri);
}
public void testGetUriFromActionMapper3() throws Exception {
public void testGetUriFromActionMapper3() {
DefaultActionMapper mapper = new DefaultActionMapper();
ActionMapping actionMapping = new ActionMapping();
actionMapping.setMethod("myMethod");
@@ -693,7 +693,7 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
}
public void testGetUriFromActionMapper4() throws Exception {
public void testGetUriFromActionMapper4() {
DefaultActionMapper mapper = new DefaultActionMapper();
ActionMapping actionMapping = new ActionMapping();
actionMapping.setName("myActionName");
@@ -703,7 +703,7 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertEquals("/myActionName.action", uri);
}
public void testGetUriFromActionMapper5() throws Exception {
public void testGetUriFromActionMapper5() {
DefaultActionMapper mapper = new DefaultActionMapper();
ActionMapping actionMapping = new ActionMapping();
actionMapping.setName("myActionName");
@@ -714,7 +714,7 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
}
//
public void testGetUriFromActionMapper6() throws Exception {
public void testGetUriFromActionMapper6() {
DefaultActionMapper mapper = new DefaultActionMapper();
ActionMapping actionMapping = new ActionMapping();
actionMapping.setMethod("myMethod");
@@ -725,7 +725,7 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertEquals("/myNamespace/myActionName!myMethod.action?test=bla", uri);
}
public void testGetUriFromActionMapper7() throws Exception {
public void testGetUriFromActionMapper7() {
DefaultActionMapper mapper = new DefaultActionMapper();
ActionMapping actionMapping = new ActionMapping();
actionMapping.setMethod("myMethod");
@@ -736,7 +736,7 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertEquals("/myActionName!myMethod.action?test=bla", uri);
}
public void testGetUriFromActionMapper8() throws Exception {
public void testGetUriFromActionMapper8() {
DefaultActionMapper mapper = new DefaultActionMapper();
ActionMapping actionMapping = new ActionMapping();
actionMapping.setMethod("myMethod");
@@ -748,7 +748,7 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
}
public void testGetUriFromActionMapper9() throws Exception {
public void testGetUriFromActionMapper9() {
DefaultActionMapper mapper = new DefaultActionMapper();
ActionMapping actionMapping = new ActionMapping();
actionMapping.setName("myActionName?test=bla");
@@ -758,7 +758,7 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertEquals("/myActionName.action?test=bla", uri);
}
public void testGetUriFromActionMapper10() throws Exception {
public void testGetUriFromActionMapper10() {
DefaultActionMapper mapper = new DefaultActionMapper();
ActionMapping actionMapping = new ActionMapping();
actionMapping.setName("myActionName?test=bla");
@@ -768,7 +768,7 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertEquals("/myActionName.action?test=bla", uri);
}
public void testGetUriFromActionMapper11() throws Exception {
public void testGetUriFromActionMapper11() {
DefaultActionMapper mapper = new DefaultActionMapper();
ActionMapping actionMapping = new ActionMapping();
actionMapping.setName("myActionName.action");
@@ -778,7 +778,7 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertEquals("/myActionName.action", uri);
}
public void testGetUriFromActionMapper12() throws Exception {
public void testGetUriFromActionMapper12() {
DefaultActionMapper mapper = new DefaultActionMapper();
ActionMapping actionMapping = new ActionMapping();
actionMapping.setName("myActionName.action");
@@ -788,7 +788,7 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertEquals("/myActionName.action", uri);
}
public void testGetUriFromActionMapper_justActionAndMethod() throws Exception {
public void testGetUriFromActionMapper_justActionAndMethod() {
DefaultActionMapper mapper = new DefaultActionMapper();
ActionMapping actionMapping = new ActionMapping();
actionMapping.setMethod("myMethod");
@@ -799,7 +799,7 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertEquals("myActionName!myMethod", uri);
}
public void testGetUriFromActionMapperWhenBlankExtension() throws Exception {
public void testGetUriFromActionMapperWhenBlankExtension() {
DefaultActionMapper mapper = new DefaultActionMapper();
mapper.setExtensions(",,");
ActionMapping actionMapping = new ActionMapping();
@@ -811,7 +811,7 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertEquals("/myNamespace/myActionName!myMethod", uri);
}
public void testSetExtension() throws Exception {
public void testSetExtension() {
DefaultActionMapper mapper = new DefaultActionMapper();
mapper.setExtensions("");
assertNull(mapper.extensions);
@@ -828,15 +828,40 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertEquals(Arrays.asList("html", "", "xml"), mapper.extensions);
mapper.setExtensions("xml");
assertEquals(Arrays.asList("xml"), mapper.extensions);
assertEquals(Collections.singletonList("xml"), mapper.extensions);
mapper.setExtensions(",");
assertEquals(Arrays.asList(""), mapper.extensions);
assertEquals(Collections.singletonList(""), mapper.extensions);
}
public void testAllowedActionNames() throws Exception {
public void testAllowedNamespaceNames() {
DefaultActionMapper mapper = new DefaultActionMapper();
String namespace = "/";
assertEquals(namespace, mapper.cleanupNamespaceName(namespace));
namespace = "${namespace}";
assertEquals(mapper.defaultNamespaceName, mapper.cleanupNamespaceName(namespace));
namespace = "${${%{namespace}}}";
assertEquals(mapper.defaultNamespaceName, mapper.cleanupNamespaceName(namespace));
namespace = "${#foo='namespace',#foo}";
assertEquals(mapper.defaultNamespaceName, mapper.cleanupNamespaceName(namespace));
namespace = "/test-namespace/namespace/";
assertEquals("/test-namespace/namespace/", mapper.cleanupNamespaceName(namespace));
namespace = "/test_namespace/namespace-test/";
assertEquals("/test_namespace/namespace-test/", mapper.cleanupNamespaceName(namespace));
namespace = "/test_namespace/namespace.test/";
assertEquals("/test_namespace/namespace.test/", mapper.cleanupActionName(namespace));
}
public void testAllowedActionNames() {
DefaultActionMapper mapper = new DefaultActionMapper();
String actionName = "action";
@@ -861,7 +886,7 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
assertEquals("test!bar.action", mapper.cleanupActionName(actionName));
}
public void testAllowedMethodNames() throws Exception {
public void testAllowedMethodNames() {
DefaultActionMapper mapper = new DefaultActionMapper();
assertEquals("", mapper.cleanupMethodName(""));
@@ -51,7 +51,7 @@ public class IncludeTagTest extends AbstractTagTest {
public void testIncludeNoParam() throws Exception {
// use always matcher as we can not determine the excact objects used in mock.include(request, response) call
// Use always matcher as we can not determine the exact objects used in mock.include(request, response) call
mockRequestDispatcher.include(anyObject(ServletRequest.class), anyObject(ServletResponse.class));
expectLastCall().times(1);
@@ -69,7 +69,7 @@ public class IncludeTagTest extends AbstractTagTest {
public void testIncludeWithParameters() throws Exception {
// use always matcher as we can not determine the excact objects used in mock.include(request, response) call
// Use always matcher as we can not determine the exact objects used in mock.include(request, response) call
mockRequestDispatcher.include(anyObject(ServletRequest.class), anyObject(ServletResponse.class));
expectLastCall().times(1);
@@ -90,7 +90,7 @@ public class IncludeTagTest extends AbstractTagTest {
public void testIncludeRelative2Dots() throws Exception {
// TODO: we should test for .. in unit test - is this test correct?
// use always matcher as we can not determine the exact objects used in mock.include(request, response) call
// Use always matcher as we can not determine the exact objects used in mock.include(request, response) call
mockRequestDispatcher.include(anyObject(ServletRequest.class), anyObject(ServletResponse.class));
expectLastCall().times(1);
@@ -108,6 +108,60 @@ public class IncludeTagTest extends AbstractTagTest {
verify(mockRequestDispatcher);
}
public void testIncludeSetUseResponseEncodingTrue() throws Exception {
// TODO: If possible in future mock-test an actual content-includes with various encodings
// while setting the response encoding to match. Doesn't appear to be possible
// right now in unit-test form.
// Seems that the best we can do is verify the setUseResponseEncoding() doesn't fail...
// Use always matcher as we can not determine the exact objects used in mock.include(request, response) call
mockRequestDispatcher.include(anyObject(ServletRequest.class), anyObject(ServletResponse.class));
expectLastCall().times(1);
replay(mockRequestDispatcher);
tag.setValue("person/create.jsp");
response.setCharacterEncoding("UTF-8");
tag.doStartTag();
// Manipulate after doStartTag to ensure the tag component has undergone injection
Include include = (Include) tag.getComponent();
include.setUseResponseEncoding("true");
tag.doEndTag();
assertEquals("UTF-8", response.getCharacterEncoding());
assertEquals("/person/create.jsp", request.getRequestDispatherString());
assertEquals("", writer.toString()); // Nothing gets written for mock-include
verify(mockRequestDispatcher);
}
public void testIncludeSetUseResponseEncodingFalse() throws Exception {
// TODO: If possible in future mock-test an actual content-includes with various encodings
// while setting the response encoding to match. Doesn't appear to be possible
// right now in unit-test form.
// Seems that the best we can do is verify the setUseResponseEncoding() doesn't fail...
// Use always matcher as we can not determine the exact objects used in mock.include(request, response) call
mockRequestDispatcher.include(anyObject(ServletRequest.class), anyObject(ServletResponse.class));
expectLastCall().times(1);
replay(mockRequestDispatcher);
tag.setValue("person/create.jsp");
response.setCharacterEncoding("UTF-8");
tag.doStartTag();
// Manipulate after doStartTag to ensure the tag component has undergone injection
Include include = (Include) tag.getComponent();
include.setUseResponseEncoding("false");
tag.doEndTag();
assertEquals("UTF-8", response.getCharacterEncoding());
assertEquals("/person/create.jsp", request.getRequestDispatherString());
assertEquals("", writer.toString()); // Nothing gets written for mock-include
verify(mockRequestDispatcher);
}
protected void setUp() throws Exception {
super.setUp();
request.setupGetRequestDispatcher(new MockRequestDispatcher());
@@ -18,6 +18,8 @@
*/
package org.apache.struts2.views.jsp;
import com.mockobjects.servlet.MockJspWriter;
import java.io.IOException;
import javax.servlet.jsp.JspException;
@@ -83,6 +85,42 @@ public class SetTagTest extends AbstractUITagTest {
assertEquals(chewie, context.get("chewie"));
}
public void testSetTrimBody() throws JspException, IOException {
final String beginEndSpaceString = " Preceding and trailing spaces. ";
final String trimmedBeginEndSpaceString = beginEndSpaceString.trim();
StrutsMockBodyContent mockBodyContent;
tag.setName("foo");
tag.setValue(null);
// Do not set any value - default for tag should be true
mockBodyContent = new StrutsMockBodyContent(new MockJspWriter());
mockBodyContent.setString(beginEndSpaceString);
tag.setBodyContent(mockBodyContent);
tag.doStartTag();
tag.doEndTag();
assertEquals(trimmedBeginEndSpaceString, context.get("foo"));
tag.setName("foo");
tag.setValue(null);
tag.setTrimBody(true);
mockBodyContent = new StrutsMockBodyContent(new MockJspWriter());
mockBodyContent.setString(beginEndSpaceString);
tag.setBodyContent(mockBodyContent);
tag.doStartTag();
tag.doEndTag();
assertEquals(trimmedBeginEndSpaceString, context.get("foo"));
tag.setName("foo");
tag.setValue(null);
tag.setTrimBody(false);
mockBodyContent = new StrutsMockBodyContent(new MockJspWriter());
mockBodyContent.setString(beginEndSpaceString);
tag.setBodyContent(mockBodyContent);
tag.doStartTag();
tag.doEndTag();
assertEquals(beginEndSpaceString, context.get("foo"));
}
protected void setUp() throws Exception {
super.setUp();
@@ -253,4 +253,40 @@ public class OptGroupTest extends AbstractUITagTest {
verify(SelectTag.class.getResource("OptGroup-6.txt"));
}
public void testOptGroupListAttributes() throws Exception {
SelectTag selectTag = new SelectTag();
selectTag.setName("mySelection");
selectTag.setLabel("My Selection");
selectTag.setList("#{'ONE':'one','TWO':'two','THREE':'three'}");
selectTag.setListCssClass("'option-css-class ' + key");
selectTag.setListCssStyle("'background-color: green; font-family: ' + key");
selectTag.setListTitle("'option-title' + key");
OptGroupTag optGroupTag1 = new OptGroupTag();
optGroupTag1.setLabel("My Label 1");
optGroupTag1.setList("#{'AAA':'aaa','BBB':'bbb','CCC':'ccc'}");
optGroupTag1.setListCssClass("'optgroup-option-css-class ' + key");
optGroupTag1.setListCssStyle("'background-color: blue; font-family: ' + key");
optGroupTag1.setListTitle("'optgroup-option-title' + key");
OptGroupTag optGroupTag2 = new OptGroupTag();
optGroupTag2.setLabel("My Label 2");
optGroupTag2.setList("#{'DDD':'ddd','EEE':'eee','FFF':'fff'}");
optGroupTag2.setListCssClass("notExistingProperty");
optGroupTag2.setListCssStyle("notExistingProperty");
optGroupTag2.setListTitle("notExistingProperty");
selectTag.setPageContext(pageContext);
selectTag.doStartTag();
optGroupTag1.setPageContext(pageContext);
optGroupTag1.doStartTag();
optGroupTag1.doEndTag();
optGroupTag2.setPageContext(pageContext);
optGroupTag2.doStartTag();
optGroupTag2.doEndTag();
selectTag.doEndTag();
//System.out.println(writer.toString());
verify(SelectTag.class.getResource("OptGroup-8.txt"));
}
}
@@ -0,0 +1,88 @@
<?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 xwork PUBLIC
"-//Apache Struts//XWork 2.5//EN"
"http://struts.apache.org/dtds/xwork-2.5.dtd"
>
<xwork>
<constant name="struts.devMode" value="false" />
<constant name="devMode" value="false" />
<constant name="struts.i18n.reload" value="false" />
<constant name="logMissingProperties" value="false" />
<constant name="enableOGNLExpressionCache" value="true" />
<constant name="enableOGNLEvalExpression" value="false" />
<constant name="reloadXmlConfiguration" value="false" />
<constant name="struts.ognl.allowStaticMethodAccess" value="false" />
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.dispatcher.errorHandler" value="struts" />
<bean class="com.opensymphony.xwork2.ObjectFactory" name="default" />
<bean class="org.apache.struts2.views.freemarker.FreemarkerThemeTemplateLoader" />
<bean class="org.apache.struts2.views.freemarker.FreemarkerManager" name="default" />
<bean class="org.apache.struts2.views.velocity.VelocityManager" name="default" optional="true" />
<bean class="org.apache.struts2.components.template.TemplateEngineManager" />
<bean class="com.opensymphony.xwork2.conversion.impl.XWorkBasicConverter" />
<bean class="com.opensymphony.xwork2.ognl.OgnlUtil" />
<bean class="org.apache.struts2.views.jsp.ui.OgnlTool" />
<bean type="com.opensymphony.xwork2.ActionProxyFactory" name="default" class="org.apache.struts2.factory.StrutsActionProxyFactory"/>
<bean type="com.opensymphony.xwork2.FileManager" name="system" class="com.opensymphony.xwork2.util.fs.DefaultFileManager" scope="singleton"/>
<bean type="com.opensymphony.xwork2.FileManagerFactory" name="default" class="com.opensymphony.xwork2.util.fs.DefaultFileManagerFactory" scope="singleton"/>
<bean type="com.opensymphony.xwork2.LocalizedTextProvider" name="global-only" class="com.opensymphony.xwork2.util.GlobalLocalizedTextProvider" scope="singleton" />
<bean type="com.opensymphony.xwork2.LocalizedTextProvider" name="default" class="com.opensymphony.xwork2.util.StrutsLocalizedTextProvider" scope="singleton" />
<bean type="com.opensymphony.xwork2.TextProvider" name="system" class="com.opensymphony.xwork2.DefaultTextProvider" scope="singleton" />
<bean type="com.opensymphony.xwork2.conversion.ConversionAnnotationProcessor" name="default" class="com.opensymphony.xwork2.conversion.impl.DefaultConversionAnnotationProcessor" />
<bean type="com.opensymphony.xwork2.conversion.ConversionFileProcessor" name="default" class="com.opensymphony.xwork2.conversion.impl.DefaultConversionFileProcessor" />
<bean type="com.opensymphony.xwork2.conversion.ObjectTypeDeterminer" name="default" class="com.opensymphony.xwork2.conversion.impl.DefaultObjectTypeDeterminer"/>
<bean type="com.opensymphony.xwork2.conversion.TypeConverterCreator" name="default" class="com.opensymphony.xwork2.conversion.impl.DefaultTypeConverterCreator" />
<bean type="com.opensymphony.xwork2.conversion.TypeConverterHolder" name="default" class="com.opensymphony.xwork2.conversion.impl.DefaultTypeConverterHolder" />
<bean type="com.opensymphony.xwork2.conversion.impl.XWorkConverter" name="default" class="com.opensymphony.xwork2.conversion.impl.XWorkConverter" />
<bean type="com.opensymphony.xwork2.factory.ActionFactory" name="default" class="com.opensymphony.xwork2.factory.DefaultActionFactory" />
<bean type="com.opensymphony.xwork2.factory.ConverterFactory" name="default" class="com.opensymphony.xwork2.factory.DefaultConverterFactory" />
<bean type="com.opensymphony.xwork2.factory.ResultFactory" name="default" class="org.apache.struts2.factory.StrutsResultFactory" />
<bean type="com.opensymphony.xwork2.factory.UnknownHandlerFactory" name="default" class="com.opensymphony.xwork2.factory.DefaultUnknownHandlerFactory" />
<bean type="com.opensymphony.xwork2.factory.ValidatorFactory" name="default" class="com.opensymphony.xwork2.factory.DefaultValidatorFactory" />
<bean type="com.opensymphony.xwork2.factory.InterceptorFactory" name="default" class="com.opensymphony.xwork2.factory.DefaultInterceptorFactory" />
<bean type="com.opensymphony.xwork2.util.ValueStackFactory" name="default" class="com.opensymphony.xwork2.ognl.OgnlValueStackFactory" />
<bean type="com.opensymphony.xwork2.util.reflection.ReflectionProvider" name="default" class="com.opensymphony.xwork2.ognl.OgnlReflectionProvider" />
<bean type="ognl.MethodAccessor" name="java.lang.Object" class="com.opensymphony.xwork2.ognl.accessor.XWorkMethodAccessor" />
<bean type="ognl.MethodAccessor" name="com.opensymphony.xwork2.util.CompoundRoot" class="com.opensymphony.xwork2.ognl.accessor.CompoundRootAccessor" />
<bean type="ognl.PropertyAccessor" name="com.opensymphony.xwork2.util.CompoundRoot" class="com.opensymphony.xwork2.ognl.accessor.CompoundRootAccessor" />
<bean type="ognl.PropertyAccessor" name="org.apache.struts2.dispatcher.HttpParameters" class="com.opensymphony.xwork2.ognl.accessor.HttpParametersPropertyAccessor" />
<bean type="ognl.PropertyAccessor" name="com.opensymphony.xwork2.ognl.ObjectProxy" class="com.opensymphony.xwork2.ognl.accessor.ObjectProxyPropertyAccessor" />
<bean type="ognl.PropertyAccessor" name="org.apache.struts2.dispatcher.Parameter" class="com.opensymphony.xwork2.ognl.accessor.ParameterPropertyAccessor" />
<bean type="ognl.PropertyAccessor" name="java.util.ArrayList" class="com.opensymphony.xwork2.ognl.accessor.XWorkListPropertyAccessor" />
<bean type="ognl.PropertyAccessor" name="java.util.Collection" class="com.opensymphony.xwork2.ognl.accessor.XWorkCollectionPropertyAccessor" />
<bean type="ognl.PropertyAccessor" name="java.util.Enumeration" class="com.opensymphony.xwork2.ognl.accessor.XWorkEnumerationAccessor" />
<bean type="ognl.PropertyAccessor" name="java.util.HashMap" class="com.opensymphony.xwork2.ognl.accessor.XWorkMapPropertyAccessor" />
<bean type="ognl.PropertyAccessor" name="java.util.HashSet" class="com.opensymphony.xwork2.ognl.accessor.XWorkCollectionPropertyAccessor" />
<bean type="ognl.PropertyAccessor" name="java.util.Iterator" class="com.opensymphony.xwork2.ognl.accessor.XWorkIteratorPropertyAccessor" />
<bean type="ognl.PropertyAccessor" name="java.util.List" class="com.opensymphony.xwork2.ognl.accessor.XWorkListPropertyAccessor" />
<bean type="ognl.PropertyAccessor" name="java.util.Map" class="com.opensymphony.xwork2.ognl.accessor.XWorkMapPropertyAccessor" />
<bean type="ognl.PropertyAccessor" name="java.lang.Object" class="com.opensymphony.xwork2.ognl.accessor.ObjectAccessor" />
<bean type="ognl.PropertyAccessor" name="java.util.Set" class="com.opensymphony.xwork2.ognl.accessor.XWorkCollectionPropertyAccessor" />
</xwork>
@@ -0,0 +1,88 @@
<?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 xwork PUBLIC
"-//Apache Struts//XWork 2.5//EN"
"http://struts.apache.org/dtds/xwork-2.5.dtd"
>
<xwork>
<constant name="struts.devMode" value="true" />
<constant name="devMode" value="true" />
<constant name="struts.i18n.reload" value="false" />
<constant name="logMissingProperties" value="false" />
<constant name="enableOGNLExpressionCache" value="true" />
<constant name="enableOGNLEvalExpression" value="false" />
<constant name="reloadXmlConfiguration" value="false" />
<constant name="struts.ognl.allowStaticMethodAccess" value="true" />
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.dispatcher.errorHandler" value="struts" />
<bean class="com.opensymphony.xwork2.ObjectFactory" name="default" />
<bean class="org.apache.struts2.views.freemarker.FreemarkerThemeTemplateLoader" />
<bean class="org.apache.struts2.views.freemarker.FreemarkerManager" name="default" />
<bean class="org.apache.struts2.views.velocity.VelocityManager" name="default" optional="true" />
<bean class="org.apache.struts2.components.template.TemplateEngineManager" />
<bean class="com.opensymphony.xwork2.conversion.impl.XWorkBasicConverter" />
<bean class="com.opensymphony.xwork2.ognl.OgnlUtil" />
<bean class="org.apache.struts2.views.jsp.ui.OgnlTool" />
<bean type="com.opensymphony.xwork2.ActionProxyFactory" name="default" class="org.apache.struts2.factory.StrutsActionProxyFactory"/>
<bean type="com.opensymphony.xwork2.FileManager" name="system" class="com.opensymphony.xwork2.util.fs.DefaultFileManager" scope="singleton"/>
<bean type="com.opensymphony.xwork2.FileManagerFactory" name="default" class="com.opensymphony.xwork2.util.fs.DefaultFileManagerFactory" scope="singleton"/>
<bean type="com.opensymphony.xwork2.LocalizedTextProvider" name="global-only" class="com.opensymphony.xwork2.util.GlobalLocalizedTextProvider" scope="singleton" />
<bean type="com.opensymphony.xwork2.LocalizedTextProvider" name="default" class="com.opensymphony.xwork2.util.StrutsLocalizedTextProvider" scope="singleton" />
<bean type="com.opensymphony.xwork2.TextProvider" name="system" class="com.opensymphony.xwork2.DefaultTextProvider" scope="singleton" />
<bean type="com.opensymphony.xwork2.conversion.ConversionAnnotationProcessor" name="default" class="com.opensymphony.xwork2.conversion.impl.DefaultConversionAnnotationProcessor" />
<bean type="com.opensymphony.xwork2.conversion.ConversionFileProcessor" name="default" class="com.opensymphony.xwork2.conversion.impl.DefaultConversionFileProcessor" />
<bean type="com.opensymphony.xwork2.conversion.ObjectTypeDeterminer" name="default" class="com.opensymphony.xwork2.conversion.impl.DefaultObjectTypeDeterminer"/>
<bean type="com.opensymphony.xwork2.conversion.TypeConverterCreator" name="default" class="com.opensymphony.xwork2.conversion.impl.DefaultTypeConverterCreator" />
<bean type="com.opensymphony.xwork2.conversion.TypeConverterHolder" name="default" class="com.opensymphony.xwork2.conversion.impl.DefaultTypeConverterHolder" />
<bean type="com.opensymphony.xwork2.conversion.impl.XWorkConverter" name="default" class="com.opensymphony.xwork2.conversion.impl.XWorkConverter" />
<bean type="com.opensymphony.xwork2.factory.ActionFactory" name="default" class="com.opensymphony.xwork2.factory.DefaultActionFactory" />
<bean type="com.opensymphony.xwork2.factory.ConverterFactory" name="default" class="com.opensymphony.xwork2.factory.DefaultConverterFactory" />
<bean type="com.opensymphony.xwork2.factory.ResultFactory" name="default" class="org.apache.struts2.factory.StrutsResultFactory" />
<bean type="com.opensymphony.xwork2.factory.UnknownHandlerFactory" name="default" class="com.opensymphony.xwork2.factory.DefaultUnknownHandlerFactory" />
<bean type="com.opensymphony.xwork2.factory.ValidatorFactory" name="default" class="com.opensymphony.xwork2.factory.DefaultValidatorFactory" />
<bean type="com.opensymphony.xwork2.factory.InterceptorFactory" name="default" class="com.opensymphony.xwork2.factory.DefaultInterceptorFactory" />
<bean type="com.opensymphony.xwork2.util.ValueStackFactory" name="default" class="com.opensymphony.xwork2.ognl.OgnlValueStackFactory" />
<bean type="com.opensymphony.xwork2.util.reflection.ReflectionProvider" name="default" class="com.opensymphony.xwork2.ognl.OgnlReflectionProvider" />
<bean type="ognl.MethodAccessor" name="java.lang.Object" class="com.opensymphony.xwork2.ognl.accessor.XWorkMethodAccessor" />
<bean type="ognl.MethodAccessor" name="com.opensymphony.xwork2.util.CompoundRoot" class="com.opensymphony.xwork2.ognl.accessor.CompoundRootAccessor" />
<bean type="ognl.PropertyAccessor" name="com.opensymphony.xwork2.util.CompoundRoot" class="com.opensymphony.xwork2.ognl.accessor.CompoundRootAccessor" />
<bean type="ognl.PropertyAccessor" name="org.apache.struts2.dispatcher.HttpParameters" class="com.opensymphony.xwork2.ognl.accessor.HttpParametersPropertyAccessor" />
<bean type="ognl.PropertyAccessor" name="com.opensymphony.xwork2.ognl.ObjectProxy" class="com.opensymphony.xwork2.ognl.accessor.ObjectProxyPropertyAccessor" />
<bean type="ognl.PropertyAccessor" name="org.apache.struts2.dispatcher.Parameter" class="com.opensymphony.xwork2.ognl.accessor.ParameterPropertyAccessor" />
<bean type="ognl.PropertyAccessor" name="java.util.ArrayList" class="com.opensymphony.xwork2.ognl.accessor.XWorkListPropertyAccessor" />
<bean type="ognl.PropertyAccessor" name="java.util.Collection" class="com.opensymphony.xwork2.ognl.accessor.XWorkCollectionPropertyAccessor" />
<bean type="ognl.PropertyAccessor" name="java.util.Enumeration" class="com.opensymphony.xwork2.ognl.accessor.XWorkEnumerationAccessor" />
<bean type="ognl.PropertyAccessor" name="java.util.HashMap" class="com.opensymphony.xwork2.ognl.accessor.XWorkMapPropertyAccessor" />
<bean type="ognl.PropertyAccessor" name="java.util.HashSet" class="com.opensymphony.xwork2.ognl.accessor.XWorkCollectionPropertyAccessor" />
<bean type="ognl.PropertyAccessor" name="java.util.Iterator" class="com.opensymphony.xwork2.ognl.accessor.XWorkIteratorPropertyAccessor" />
<bean type="ognl.PropertyAccessor" name="java.util.List" class="com.opensymphony.xwork2.ognl.accessor.XWorkListPropertyAccessor" />
<bean type="ognl.PropertyAccessor" name="java.util.Map" class="com.opensymphony.xwork2.ognl.accessor.XWorkMapPropertyAccessor" />
<bean type="ognl.PropertyAccessor" name="java.lang.Object" class="com.opensymphony.xwork2.ognl.accessor.ObjectAccessor" />
<bean type="ognl.PropertyAccessor" name="java.util.Set" class="com.opensymphony.xwork2.ognl.accessor.XWorkCollectionPropertyAccessor" />
</xwork>
@@ -0,0 +1,88 @@
<?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 xwork PUBLIC
"-//Apache Struts//XWork 2.5//EN"
"http://struts.apache.org/dtds/xwork-2.5.dtd"
>
<xwork>
<constant name="struts.devMode" value="false" />
<constant name="devMode" value="false" />
<constant name="struts.i18n.reload" value="false" />
<constant name="logMissingProperties" value="false" />
<constant name="enableOGNLExpressionCache" value="true" />
<constant name="enableOGNLEvalExpression" value="false" />
<constant name="reloadXmlConfiguration" value="false" />
<constant name="struts.ognl.allowStaticMethodAccess" value="true" />
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.dispatcher.errorHandler" value="struts" />
<bean class="com.opensymphony.xwork2.ObjectFactory" name="default" />
<bean class="org.apache.struts2.views.freemarker.FreemarkerThemeTemplateLoader" />
<bean class="org.apache.struts2.views.freemarker.FreemarkerManager" name="default" />
<bean class="org.apache.struts2.views.velocity.VelocityManager" name="default" optional="true" />
<bean class="org.apache.struts2.components.template.TemplateEngineManager" />
<bean class="com.opensymphony.xwork2.conversion.impl.XWorkBasicConverter" />
<bean class="com.opensymphony.xwork2.ognl.OgnlUtil" />
<bean class="org.apache.struts2.views.jsp.ui.OgnlTool" />
<bean type="com.opensymphony.xwork2.ActionProxyFactory" name="default" class="org.apache.struts2.factory.StrutsActionProxyFactory"/>
<bean type="com.opensymphony.xwork2.FileManager" name="system" class="com.opensymphony.xwork2.util.fs.DefaultFileManager" scope="singleton"/>
<bean type="com.opensymphony.xwork2.FileManagerFactory" name="default" class="com.opensymphony.xwork2.util.fs.DefaultFileManagerFactory" scope="singleton"/>
<bean type="com.opensymphony.xwork2.LocalizedTextProvider" name="global-only" class="com.opensymphony.xwork2.util.GlobalLocalizedTextProvider" scope="singleton" />
<bean type="com.opensymphony.xwork2.LocalizedTextProvider" name="default" class="com.opensymphony.xwork2.util.StrutsLocalizedTextProvider" scope="singleton" />
<bean type="com.opensymphony.xwork2.TextProvider" name="system" class="com.opensymphony.xwork2.DefaultTextProvider" scope="singleton" />
<bean type="com.opensymphony.xwork2.conversion.ConversionAnnotationProcessor" name="default" class="com.opensymphony.xwork2.conversion.impl.DefaultConversionAnnotationProcessor" />
<bean type="com.opensymphony.xwork2.conversion.ConversionFileProcessor" name="default" class="com.opensymphony.xwork2.conversion.impl.DefaultConversionFileProcessor" />
<bean type="com.opensymphony.xwork2.conversion.ObjectTypeDeterminer" name="default" class="com.opensymphony.xwork2.conversion.impl.DefaultObjectTypeDeterminer"/>
<bean type="com.opensymphony.xwork2.conversion.TypeConverterCreator" name="default" class="com.opensymphony.xwork2.conversion.impl.DefaultTypeConverterCreator" />
<bean type="com.opensymphony.xwork2.conversion.TypeConverterHolder" name="default" class="com.opensymphony.xwork2.conversion.impl.DefaultTypeConverterHolder" />
<bean type="com.opensymphony.xwork2.conversion.impl.XWorkConverter" name="default" class="com.opensymphony.xwork2.conversion.impl.XWorkConverter" />
<bean type="com.opensymphony.xwork2.factory.ActionFactory" name="default" class="com.opensymphony.xwork2.factory.DefaultActionFactory" />
<bean type="com.opensymphony.xwork2.factory.ConverterFactory" name="default" class="com.opensymphony.xwork2.factory.DefaultConverterFactory" />
<bean type="com.opensymphony.xwork2.factory.ResultFactory" name="default" class="org.apache.struts2.factory.StrutsResultFactory" />
<bean type="com.opensymphony.xwork2.factory.UnknownHandlerFactory" name="default" class="com.opensymphony.xwork2.factory.DefaultUnknownHandlerFactory" />
<bean type="com.opensymphony.xwork2.factory.ValidatorFactory" name="default" class="com.opensymphony.xwork2.factory.DefaultValidatorFactory" />
<bean type="com.opensymphony.xwork2.factory.InterceptorFactory" name="default" class="com.opensymphony.xwork2.factory.DefaultInterceptorFactory" />
<bean type="com.opensymphony.xwork2.util.ValueStackFactory" name="default" class="com.opensymphony.xwork2.ognl.OgnlValueStackFactory" />
<bean type="com.opensymphony.xwork2.util.reflection.ReflectionProvider" name="default" class="com.opensymphony.xwork2.ognl.OgnlReflectionProvider" />
<bean type="ognl.MethodAccessor" name="java.lang.Object" class="com.opensymphony.xwork2.ognl.accessor.XWorkMethodAccessor" />
<bean type="ognl.MethodAccessor" name="com.opensymphony.xwork2.util.CompoundRoot" class="com.opensymphony.xwork2.ognl.accessor.CompoundRootAccessor" />
<bean type="ognl.PropertyAccessor" name="com.opensymphony.xwork2.util.CompoundRoot" class="com.opensymphony.xwork2.ognl.accessor.CompoundRootAccessor" />
<bean type="ognl.PropertyAccessor" name="org.apache.struts2.dispatcher.HttpParameters" class="com.opensymphony.xwork2.ognl.accessor.HttpParametersPropertyAccessor" />
<bean type="ognl.PropertyAccessor" name="com.opensymphony.xwork2.ognl.ObjectProxy" class="com.opensymphony.xwork2.ognl.accessor.ObjectProxyPropertyAccessor" />
<bean type="ognl.PropertyAccessor" name="org.apache.struts2.dispatcher.Parameter" class="com.opensymphony.xwork2.ognl.accessor.ParameterPropertyAccessor" />
<bean type="ognl.PropertyAccessor" name="java.util.ArrayList" class="com.opensymphony.xwork2.ognl.accessor.XWorkListPropertyAccessor" />
<bean type="ognl.PropertyAccessor" name="java.util.Collection" class="com.opensymphony.xwork2.ognl.accessor.XWorkCollectionPropertyAccessor" />
<bean type="ognl.PropertyAccessor" name="java.util.Enumeration" class="com.opensymphony.xwork2.ognl.accessor.XWorkEnumerationAccessor" />
<bean type="ognl.PropertyAccessor" name="java.util.HashMap" class="com.opensymphony.xwork2.ognl.accessor.XWorkMapPropertyAccessor" />
<bean type="ognl.PropertyAccessor" name="java.util.HashSet" class="com.opensymphony.xwork2.ognl.accessor.XWorkCollectionPropertyAccessor" />
<bean type="ognl.PropertyAccessor" name="java.util.Iterator" class="com.opensymphony.xwork2.ognl.accessor.XWorkIteratorPropertyAccessor" />
<bean type="ognl.PropertyAccessor" name="java.util.List" class="com.opensymphony.xwork2.ognl.accessor.XWorkListPropertyAccessor" />
<bean type="ognl.PropertyAccessor" name="java.util.Map" class="com.opensymphony.xwork2.ognl.accessor.XWorkMapPropertyAccessor" />
<bean type="ognl.PropertyAccessor" name="java.lang.Object" class="com.opensymphony.xwork2.ognl.accessor.ObjectAccessor" />
<bean type="ognl.PropertyAccessor" name="java.util.Set" class="com.opensymphony.xwork2.ognl.accessor.XWorkCollectionPropertyAccessor" />
</xwork>
@@ -0,0 +1,88 @@
<?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 xwork PUBLIC
"-//Apache Struts//XWork 2.5//EN"
"http://struts.apache.org/dtds/xwork-2.5.dtd"
>
<xwork>
<constant name="struts.devMode" value="true" />
<constant name="devMode" value="true" />
<constant name="struts.i18n.reload" value="false" />
<constant name="logMissingProperties" value="false" />
<constant name="enableOGNLExpressionCache" value="true" />
<constant name="enableOGNLEvalExpression" value="false" />
<constant name="reloadXmlConfiguration" value="false" />
<constant name="struts.ognl.allowStaticMethodAccess" value="false" />
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.dispatcher.errorHandler" value="struts" />
<bean class="com.opensymphony.xwork2.ObjectFactory" name="default" />
<bean class="org.apache.struts2.views.freemarker.FreemarkerThemeTemplateLoader" />
<bean class="org.apache.struts2.views.freemarker.FreemarkerManager" name="default" />
<bean class="org.apache.struts2.views.velocity.VelocityManager" name="default" optional="true" />
<bean class="org.apache.struts2.components.template.TemplateEngineManager" />
<bean class="com.opensymphony.xwork2.conversion.impl.XWorkBasicConverter" />
<bean class="com.opensymphony.xwork2.ognl.OgnlUtil" />
<bean class="org.apache.struts2.views.jsp.ui.OgnlTool" />
<bean type="com.opensymphony.xwork2.ActionProxyFactory" name="default" class="org.apache.struts2.factory.StrutsActionProxyFactory"/>
<bean type="com.opensymphony.xwork2.FileManager" name="system" class="com.opensymphony.xwork2.util.fs.DefaultFileManager" scope="singleton"/>
<bean type="com.opensymphony.xwork2.FileManagerFactory" name="default" class="com.opensymphony.xwork2.util.fs.DefaultFileManagerFactory" scope="singleton"/>
<bean type="com.opensymphony.xwork2.LocalizedTextProvider" name="global-only" class="com.opensymphony.xwork2.util.GlobalLocalizedTextProvider" scope="singleton" />
<bean type="com.opensymphony.xwork2.LocalizedTextProvider" name="default" class="com.opensymphony.xwork2.util.StrutsLocalizedTextProvider" scope="singleton" />
<bean type="com.opensymphony.xwork2.TextProvider" name="system" class="com.opensymphony.xwork2.DefaultTextProvider" scope="singleton" />
<bean type="com.opensymphony.xwork2.conversion.ConversionAnnotationProcessor" name="default" class="com.opensymphony.xwork2.conversion.impl.DefaultConversionAnnotationProcessor" />
<bean type="com.opensymphony.xwork2.conversion.ConversionFileProcessor" name="default" class="com.opensymphony.xwork2.conversion.impl.DefaultConversionFileProcessor" />
<bean type="com.opensymphony.xwork2.conversion.ObjectTypeDeterminer" name="default" class="com.opensymphony.xwork2.conversion.impl.DefaultObjectTypeDeterminer"/>
<bean type="com.opensymphony.xwork2.conversion.TypeConverterCreator" name="default" class="com.opensymphony.xwork2.conversion.impl.DefaultTypeConverterCreator" />
<bean type="com.opensymphony.xwork2.conversion.TypeConverterHolder" name="default" class="com.opensymphony.xwork2.conversion.impl.DefaultTypeConverterHolder" />
<bean type="com.opensymphony.xwork2.conversion.impl.XWorkConverter" name="default" class="com.opensymphony.xwork2.conversion.impl.XWorkConverter" />
<bean type="com.opensymphony.xwork2.factory.ActionFactory" name="default" class="com.opensymphony.xwork2.factory.DefaultActionFactory" />
<bean type="com.opensymphony.xwork2.factory.ConverterFactory" name="default" class="com.opensymphony.xwork2.factory.DefaultConverterFactory" />
<bean type="com.opensymphony.xwork2.factory.ResultFactory" name="default" class="org.apache.struts2.factory.StrutsResultFactory" />
<bean type="com.opensymphony.xwork2.factory.UnknownHandlerFactory" name="default" class="com.opensymphony.xwork2.factory.DefaultUnknownHandlerFactory" />
<bean type="com.opensymphony.xwork2.factory.ValidatorFactory" name="default" class="com.opensymphony.xwork2.factory.DefaultValidatorFactory" />
<bean type="com.opensymphony.xwork2.factory.InterceptorFactory" name="default" class="com.opensymphony.xwork2.factory.DefaultInterceptorFactory" />
<bean type="com.opensymphony.xwork2.util.ValueStackFactory" name="default" class="com.opensymphony.xwork2.ognl.OgnlValueStackFactory" />
<bean type="com.opensymphony.xwork2.util.reflection.ReflectionProvider" name="default" class="com.opensymphony.xwork2.ognl.OgnlReflectionProvider" />
<bean type="ognl.MethodAccessor" name="java.lang.Object" class="com.opensymphony.xwork2.ognl.accessor.XWorkMethodAccessor" />
<bean type="ognl.MethodAccessor" name="com.opensymphony.xwork2.util.CompoundRoot" class="com.opensymphony.xwork2.ognl.accessor.CompoundRootAccessor" />
<bean type="ognl.PropertyAccessor" name="com.opensymphony.xwork2.util.CompoundRoot" class="com.opensymphony.xwork2.ognl.accessor.CompoundRootAccessor" />
<bean type="ognl.PropertyAccessor" name="org.apache.struts2.dispatcher.HttpParameters" class="com.opensymphony.xwork2.ognl.accessor.HttpParametersPropertyAccessor" />
<bean type="ognl.PropertyAccessor" name="com.opensymphony.xwork2.ognl.ObjectProxy" class="com.opensymphony.xwork2.ognl.accessor.ObjectProxyPropertyAccessor" />
<bean type="ognl.PropertyAccessor" name="org.apache.struts2.dispatcher.Parameter" class="com.opensymphony.xwork2.ognl.accessor.ParameterPropertyAccessor" />
<bean type="ognl.PropertyAccessor" name="java.util.ArrayList" class="com.opensymphony.xwork2.ognl.accessor.XWorkListPropertyAccessor" />
<bean type="ognl.PropertyAccessor" name="java.util.Collection" class="com.opensymphony.xwork2.ognl.accessor.XWorkCollectionPropertyAccessor" />
<bean type="ognl.PropertyAccessor" name="java.util.Enumeration" class="com.opensymphony.xwork2.ognl.accessor.XWorkEnumerationAccessor" />
<bean type="ognl.PropertyAccessor" name="java.util.HashMap" class="com.opensymphony.xwork2.ognl.accessor.XWorkMapPropertyAccessor" />
<bean type="ognl.PropertyAccessor" name="java.util.HashSet" class="com.opensymphony.xwork2.ognl.accessor.XWorkCollectionPropertyAccessor" />
<bean type="ognl.PropertyAccessor" name="java.util.Iterator" class="com.opensymphony.xwork2.ognl.accessor.XWorkIteratorPropertyAccessor" />
<bean type="ognl.PropertyAccessor" name="java.util.List" class="com.opensymphony.xwork2.ognl.accessor.XWorkListPropertyAccessor" />
<bean type="ognl.PropertyAccessor" name="java.util.Map" class="com.opensymphony.xwork2.ognl.accessor.XWorkMapPropertyAccessor" />
<bean type="ognl.PropertyAccessor" name="java.lang.Object" class="com.opensymphony.xwork2.ognl.accessor.ObjectAccessor" />
<bean type="ognl.PropertyAccessor" name="java.util.Set" class="com.opensymphony.xwork2.ognl.accessor.XWorkCollectionPropertyAccessor" />
</xwork>
@@ -28,8 +28,16 @@
<constant name="foo" value="bar"/>
<!-- Linux/Unix (or Unix-like) Environment -->
<constant name="user" value="${env.USER}"/>
<constant name="home" value="Current HOME = ${env.HOME}"/>
<!-- Linux/Unix (or Unix-like) Environment -->
<!-- Windows (or Windows-like) Environment -->
<constant name="username" value="${env.USERNAME}"/>
<constant name="homedrive.homepath" value="Current HOMEDRIVE.HOMEPATH = ${env.HOMEDRIVE}${env.HOMEPATH}"/>
<!-- Windows (or Windows-like) Environment -->
<constant name="os" value="Current OS = ${os.name}"/>
<constant name="unknown" value="Unknown = ${env.UNKNOWN:default}"/>
@@ -0,0 +1,31 @@
<?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 xwork PUBLIC
"-//Apache Struts//XWork 2.5//EN"
"http://struts.apache.org/dtds/xwork-2.5.dtd"
>
<xwork>
<constant name="struts.configuration.xml.reload" value="true" />
</xwork>
@@ -0,0 +1,40 @@
<tr>
<td class="tdLabel"><label for="mySelection" class="label">My Selection:</label></td>
<td class="tdInput">
<select name="mySelection" id="mySelection">
<option value="ONE" class="option-css-class ONE" style="background-color: green; font-family: ONE" title="option-title ONE">one</option>
<option value="TWO" class="option-css-class TWO" style="background-color: green; font-family: TWO" title="option-title TWO">two</option>
<option value="THREE" class="option-css-class THREE" style="background-color: green; font-family: THREE" title="option-title THREE">three</option>
<optgroup
label="My Label 1"
>
<option value="AAA" class="optgroup-option-css-class AAA" style="background-color: blue; font-family: AAA" title="optgroup-option-title AAA"
>aaa
</option>
<option value="BBB" class="optgroup-option-css-class BBB" style="background-color: blue; font-family: BBB" title="optgroup-option-title BBB"
>bbb
</option>
<option value="CCC" class="optgroup-option-css-class CCC" style="background-color: blue; font-family: CCC" title="optgroup-option-title CCC"
>ccc
</option>
</optgroup>
<optgroup
label="My Label 2"
>
<option value="DDD"
>ddd
</option>
<option value="EEE"
>eee
</option>
<option value="FFF"
>fff
</option>
</optgroup>
</select>
</td>
</tr>
Vendored Executable
+286
View File
@@ -0,0 +1,286 @@
#!/bin/sh
# ----------------------------------------------------------------------------
# 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.
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
# Maven2 Start Up Batch script
#
# Required ENV vars:
# ------------------
# JAVA_HOME - location of a JDK home dir
#
# Optional ENV vars
# -----------------
# M2_HOME - location of maven2's installed home dir
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
# e.g. to debug Maven itself, use
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
# ----------------------------------------------------------------------------
if [ -z "$MAVEN_SKIP_RC" ] ; then
if [ -f /etc/mavenrc ] ; then
. /etc/mavenrc
fi
if [ -f "$HOME/.mavenrc" ] ; then
. "$HOME/.mavenrc"
fi
fi
# OS specific support. $var _must_ be set to either true or false.
cygwin=false;
darwin=false;
mingw=false
case "`uname`" in
CYGWIN*) cygwin=true ;;
MINGW*) mingw=true;;
Darwin*) darwin=true
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
if [ -z "$JAVA_HOME" ]; then
if [ -x "/usr/libexec/java_home" ]; then
export JAVA_HOME="`/usr/libexec/java_home`"
else
export JAVA_HOME="/Library/Java/Home"
fi
fi
;;
esac
if [ -z "$JAVA_HOME" ] ; then
if [ -r /etc/gentoo-release ] ; then
JAVA_HOME=`java-config --jre-home`
fi
fi
if [ -z "$M2_HOME" ] ; then
## resolve links - $0 may be a link to maven's home
PRG="$0"
# need this for relative symlinks
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG="`dirname "$PRG"`/$link"
fi
done
saveddir=`pwd`
M2_HOME=`dirname "$PRG"`/..
# make it fully qualified
M2_HOME=`cd "$M2_HOME" && pwd`
cd "$saveddir"
# echo Using m2 at $M2_HOME
fi
# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin ; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --unix "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
fi
# For Mingw, ensure paths are in UNIX format before anything is touched
if $mingw ; then
[ -n "$M2_HOME" ] &&
M2_HOME="`(cd "$M2_HOME"; pwd)`"
[ -n "$JAVA_HOME" ] &&
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
# TODO classpath?
fi
if [ -z "$JAVA_HOME" ]; then
javaExecutable="`which javac`"
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
# readlink(1) is not available as standard on Solaris 10.
readLink=`which readlink`
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
if $darwin ; then
javaHome="`dirname \"$javaExecutable\"`"
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
else
javaExecutable="`readlink -f \"$javaExecutable\"`"
fi
javaHome="`dirname \"$javaExecutable\"`"
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
JAVA_HOME="$javaHome"
export JAVA_HOME
fi
fi
fi
if [ -z "$JAVACMD" ] ; then
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
else
JAVACMD="`which java`"
fi
fi
if [ ! -x "$JAVACMD" ] ; then
echo "Error: JAVA_HOME is not defined correctly." >&2
echo " We cannot execute $JAVACMD" >&2
exit 1
fi
if [ -z "$JAVA_HOME" ] ; then
echo "Warning: JAVA_HOME environment variable is not set."
fi
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
# traverses directory structure from process work directory to filesystem root
# first directory with .mvn subdirectory is considered project base directory
find_maven_basedir() {
if [ -z "$1" ]
then
echo "Path not specified to find_maven_basedir"
return 1
fi
basedir="$1"
wdir="$1"
while [ "$wdir" != '/' ] ; do
if [ -d "$wdir"/.mvn ] ; then
basedir=$wdir
break
fi
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
if [ -d "${wdir}" ]; then
wdir=`cd "$wdir/.."; pwd`
fi
# end of workaround
done
echo "${basedir}"
}
# concatenates all lines of a file
concat_lines() {
if [ -f "$1" ]; then
echo "$(tr -s '\n' ' ' < "$1")"
fi
}
BASE_DIR=`find_maven_basedir "$(pwd)"`
if [ -z "$BASE_DIR" ]; then
exit 1;
fi
##########################################################################################
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
# This allows using the maven wrapper in projects that prohibit checking in binary data.
##########################################################################################
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found .mvn/wrapper/maven-wrapper.jar"
fi
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
fi
jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.0/maven-wrapper-0.4.0.jar"
while IFS="=" read key value; do
case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
esac
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
if [ "$MVNW_VERBOSE" = true ]; then
echo "Downloading from: $jarUrl"
fi
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
if command -v wget > /dev/null; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found wget ... using wget"
fi
wget "$jarUrl" -O "$wrapperJarPath"
elif command -v curl > /dev/null; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found curl ... using curl"
fi
curl -o "$wrapperJarPath" "$jarUrl"
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Falling back to using Java to download"
fi
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
if [ -e "$javaClass" ]; then
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Compiling MavenWrapperDownloader.java ..."
fi
# Compiling the Java class
("$JAVA_HOME/bin/javac" "$javaClass")
fi
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
# Running the downloader
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Running MavenWrapperDownloader.java ..."
fi
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
fi
fi
fi
fi
##########################################################################################
# End of extension
##########################################################################################
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
if [ "$MVNW_VERBOSE" = true ]; then
echo $MAVEN_PROJECTBASEDIR
fi
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --path --windows "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
fi
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
exec "$JAVACMD" \
$MAVEN_OPTS \
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
"-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
Vendored Executable
+161
View File
@@ -0,0 +1,161 @@
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership. The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License. You may obtain a copy of the License at
@REM
@REM http://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied. See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Maven2 Start Up Batch script
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM
@REM Optional ENV vars
@REM M2_HOME - location of maven2's installed home dir
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
@REM ----------------------------------------------------------------------------
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo off
@REM set title of command window
title %0
@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
@REM set %HOME% to equivalent of $HOME
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
:skipRcPre
@setlocal
set ERROR_CODE=0
@REM To isolate internal variables from possible post scripts, we use another setlocal
@setlocal
@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome
echo.
echo Error: JAVA_HOME not found in your environment. >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto init
echo.
echo Error: JAVA_HOME is set to an invalid directory. >&2
echo JAVA_HOME = "%JAVA_HOME%" >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
@REM ==== END VALIDATION ====
:init
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
@REM Fallback to current working directory if not found.
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
set EXEC_DIR=%CD%
set WDIR=%EXEC_DIR%
:findBaseDir
IF EXIST "%WDIR%"\.mvn goto baseDirFound
cd ..
IF "%WDIR%"=="%CD%" goto baseDirNotFound
set WDIR=%CD%
goto findBaseDir
:baseDirFound
set MAVEN_PROJECTBASEDIR=%WDIR%
cd "%EXEC_DIR%"
goto endDetectBaseDir
:baseDirNotFound
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
cd "%EXEC_DIR%"
:endDetectBaseDir
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
@setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
:endReadAdditionalConfig
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.0/maven-wrapper-0.4.0.jar"
FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO (
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
)
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
if exist %WRAPPER_JAR% (
echo Found %WRAPPER_JAR%
) else (
echo Couldn't find %WRAPPER_JAR%, downloading it ...
echo Downloading from: %DOWNLOAD_URL%
powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"
echo Finished downloading %WRAPPER_JAR%
)
@REM End of extension
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
if ERRORLEVEL 1 goto error
goto end
:error
set ERROR_CODE=1
:end
@endlocal & set ERROR_CODE=%ERROR_CODE%
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
@REM check for post script, once with legacy .bat ending and once with .cmd ending
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
:skipRcPost
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
if "%MAVEN_BATCH_PAUSE%" == "on" pause
if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
exit /B %ERROR_CODE%
+32 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>2.5.16</version>
<version>2.5.19</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -61,6 +61,37 @@
<scope>test</scope>
</dependency>
<!--
The Java EE API modules listed below are all marked @Deprecated(forRemoval=true), because they are scheduled
for removal in Java 11. So the -add-module approach will no longer work in Java 11 out of the box.
What we will need to do in Java 11 and forward is include our own copy of the Java EE APIs on the class path
or module path. For example, we can add the JAX-B APIs as a maven dependency like this:
-->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.3.0.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
+1 -1
View File
@@ -25,7 +25,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>2.5.16</version>
<version>2.5.19</version>
</parent>
<artifactId>struts2-cdi-plugin</artifactId>
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>2.5.16</version>
<version>2.5.19</version>
</parent>
<artifactId>struts2-config-browser-plugin</artifactId>
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>2.5.16</version>
<version>2.5.19</version>
</parent>
<artifactId>struts2-convention-plugin</artifactId>
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>2.5.16</version>
<version>2.5.19</version>
</parent>
<artifactId>struts2-dwr-plugin</artifactId>
+1 -2
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>2.5.16</version>
<version>2.5.19</version>
</parent>
<artifactId>struts2-embeddedjsp-plugin</artifactId>
@@ -101,7 +101,6 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<additionalClasspathElements>
<element>${project.build.testOutputDirectory}/jsps.jar</element>
@@ -80,7 +80,7 @@ public class JspCompilationContext {
protected String baseURI;
protected String outputDir;
protected ServletContext context;
protected URLClassLoader loader;
protected ClassLoader loader;
protected JspRuntimeContext rctxt;
@@ -177,7 +177,7 @@ public class JspCompilationContext {
return rctxt.getParentClassLoader();
}
public void setClassLoader(URLClassLoader loader) {
public void setClassLoader(ClassLoader loader) {
this.loader = loader;
}
@@ -33,12 +33,14 @@ import javax.servlet.jsp.JspFactory;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FilePermission;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.security.CodeSource;
import java.security.PermissionCollection;
import java.security.Policy;
import java.security.cert.Certificate;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -121,11 +123,9 @@ public final class JspRuntimeContext {
this.options = options;
// Get the parent class loader
parentClassLoader =
(URLClassLoader) Thread.currentThread().getContextClassLoader();
parentClassLoader = Thread.currentThread().getContextClassLoader();
if (parentClassLoader == null) {
parentClassLoader =
(URLClassLoader) this.getClass().getClassLoader();
parentClassLoader = this.getClass().getClassLoader();
}
if (log.isDebugEnabled()) {
@@ -138,7 +138,11 @@ public final class JspRuntimeContext {
}
}
initClassPath();
try {
initClassPath();
} catch (IOException e) {
context.log("ClassPath Init for context failed", e);
}
if (context instanceof JspCServletContext) {
return;
@@ -165,7 +169,7 @@ public final class JspRuntimeContext {
*/
private ServletContext context;
private Options options;
private URLClassLoader parentClassLoader;
private ClassLoader parentClassLoader;
private PermissionCollection permissionCollection;
private CodeSource codeSource;
private String classpath;
@@ -233,7 +237,7 @@ public final class JspRuntimeContext {
*
* @return URLClassLoader parent
*/
public URLClassLoader getParentClassLoader() {
public ClassLoader getParentClassLoader() {
return parentClassLoader;
}
@@ -333,9 +337,14 @@ public final class JspRuntimeContext {
/**
* Method used to initialize classpath for compiles.
*/
private void initClassPath() {
private void initClassPath() throws IOException {
URL[] urls = parentClassLoader.getURLs();
URL[] urls;
if (parentClassLoader instanceof URLClassLoader) {
urls = ((URLClassLoader) parentClassLoader).getURLs();
} else { //jdk9 or later
urls = Collections.list(parentClassLoader.getResources("")).toArray(new URL[0]);
}
StringBuffer cpath = new StringBuffer();
String sep = System.getProperty("path.separator");
@@ -418,34 +427,37 @@ public final class JspRuntimeContext {
permissionCollection.add(new RuntimePermission(
"accessClassInPackage.org.apache.struts2.jasper.runtime"));
URL[] urls;
if (parentClassLoader instanceof URLClassLoader) {
URL[] urls = parentClassLoader.getURLs();
String jarUrl = null;
String jndiUrl = null;
for (int i = 0; i < urls.length; i++) {
if (jndiUrl == null
&& urls[i].toString().startsWith("jndi:")) {
jndiUrl = urls[i].toString() + "-";
}
if (jarUrl == null
&& urls[i].toString().startsWith("jar:jndi:")
) {
jarUrl = urls[i].toString();
jarUrl = jarUrl.substring(0, jarUrl.length() - 2);
jarUrl = jarUrl.substring(0,
jarUrl.lastIndexOf('/')) + "/-";
}
}
if (jarUrl != null) {
permissionCollection.add(
new FilePermission(jarUrl, "read"));
permissionCollection.add(
new FilePermission(jarUrl.substring(4), "read"));
}
if (jndiUrl != null)
permissionCollection.add(
new FilePermission(jndiUrl, "read"));
urls = ((URLClassLoader) parentClassLoader).getURLs();
} else { //jdk9 or later
urls = Collections.list(parentClassLoader.getResources("")).toArray(new URL[0]);
}
String jarUrl = null;
String jndiUrl = null;
for (URL url1 : urls) {
if (jndiUrl == null
&& url1.toString().startsWith("jndi:")) {
jndiUrl = url1.toString() + "-";
}
if (jarUrl == null
&& url1.toString().startsWith("jar:jndi:")
) {
jarUrl = url1.toString();
jarUrl = jarUrl.substring(0, jarUrl.length() - 2);
jarUrl = jarUrl.substring(0,
jarUrl.lastIndexOf('/')) + "/-";
}
}
if (jarUrl != null) {
permissionCollection.add(
new FilePermission(jarUrl, "read"));
permissionCollection.add(
new FilePermission(jarUrl.substring(4), "read"));
}
if (jndiUrl != null)
permissionCollection.add(
new FilePermission(jndiUrl, "read"));
} catch (Exception e) {
context.log("Security Init for context failed", e);
}
@@ -594,8 +594,7 @@ class TagFileProcessor {
rctxt.addWrapper(tagFileJarPath + tagFilePath, wrapper);
// Use same classloader and classpath for compiling tag files
wrapper.getJspEngineContext().setClassLoader(
(URLClassLoader) ctxt.getClassLoader());
wrapper.getJspEngineContext().setClassLoader(ctxt.getClassLoader());
wrapper.getJspEngineContext().setClassPath(ctxt.getClassPath());
} else {
// Make sure that JspCompilationContext gets the latest TagInfo
@@ -25,12 +25,7 @@ import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLConnection;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import org.xml.sax.InputSource;
@@ -508,24 +503,27 @@ public class TldLocationsCache {
ClassLoader loader = webappLoader;
while (loader != null) {
URL[] urls;
if (loader instanceof URLClassLoader) {
URL[] urls = ((URLClassLoader) loader).getURLs();
for (int i=0; i<urls.length; i++) {
URLConnection conn = urls[i].openConnection();
if (conn instanceof JarURLConnection) {
if (needScanJar(loader, webappLoader,
((JarURLConnection) conn).getJarFile().getName())) {
scanJar((JarURLConnection) conn, true);
}
} else {
String urlStr = urls[i].toString();
if (urlStr.startsWith(FILE_PROTOCOL)
&& urlStr.endsWith(JAR_FILE_SUFFIX)
&& needScanJar(loader, webappLoader, urlStr)) {
URL jarURL = new URL("jar:" + urlStr + "!/");
scanJar((JarURLConnection) jarURL.openConnection(),
true);
}
urls = ((URLClassLoader) loader).getURLs();
} else { //jdk9 or later
urls = Collections.list(loader.getResources("")).toArray(new URL[0]);
}
for (URL url : urls) {
URLConnection conn = url.openConnection();
if (conn instanceof JarURLConnection) {
if (needScanJar(loader, webappLoader,
((JarURLConnection) conn).getJarFile().getName())) {
scanJar((JarURLConnection) conn, true);
}
} else {
String urlStr = url.toString();
if (urlStr.startsWith(FILE_PROTOCOL)
&& urlStr.endsWith(JAR_FILE_SUFFIX)
&& needScanJar(loader, webappLoader, urlStr)) {
URL jarURL = new URL("jar:" + urlStr + "!/");
scanJar((JarURLConnection) jarURL.openConnection(),
true);
}
}
}
@@ -31,7 +31,6 @@ import com.opensymphony.xwork2.util.ValueStack;
import com.opensymphony.xwork2.util.finder.ClassLoaderInterface;
import com.opensymphony.xwork2.util.finder.ClassLoaderInterfaceDelegate;
import com.opensymphony.xwork2.util.fs.DefaultFileManager;
import com.sun.net.httpserver.HttpsParameters;
import junit.framework.TestCase;
import org.apache.commons.lang3.StringUtils;
import org.apache.struts2.dispatcher.HttpParameters;
@@ -46,11 +45,7 @@ import javax.servlet.Servlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
@@ -231,6 +226,21 @@ public class EmbeddedJSPResultTest extends TestCase {
assertEquals("WhoamI?", StringUtils.deleteWhitespace(response.getContentAsString()));
}
public void testNotURLClassLoader() throws Exception {
ClassLoader parentClassLoader = Thread.currentThread().getContextClassLoader();
NotURLClassLoader loader = new NotURLClassLoader(parentClassLoader);
Thread.currentThread().setContextClassLoader(loader);
try {
result.setLocation("org/apache/struts2/tag0.jsp");
result.execute(null);
assertEquals("Thissessionisnotsecure.OtherText", StringUtils.deleteWhitespace(response.getContentAsString()));
} finally {
Thread.currentThread().setContextClassLoader(parentClassLoader);
}
}
@Override
protected void setUp() throws Exception {
super.setUp();
@@ -374,3 +384,10 @@ class CountingClassLoaderInterface extends ClassLoaderInterfaceDelegate {
return super.getResourceAsStream(name);
}
}
class NotURLClassLoader extends ClassLoader {
NotURLClassLoader(ClassLoader parentClassLoader) {
super(parentClassLoader);
}
}
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>2.5.16</version>
<version>2.5.19</version>
</parent>
<artifactId>struts2-gxp-plugin</artifactId>
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>2.5.16</version>
<version>2.5.19</version>
</parent>
<artifactId>struts2-jasperreports-plugin</artifactId>
+1 -1
View File
@@ -25,7 +25,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>2.5.16</version>
<version>2.5.19</version>
</parent>
<artifactId>struts2-javatemplates-plugin</artifactId>
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>2.5.16</version>
<version>2.5.19</version>
</parent>
<artifactId>struts2-jfreechart-plugin</artifactId>
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>2.5.16</version>
<version>2.5.19</version>
</parent>
<artifactId>struts2-json-plugin</artifactId>
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>2.5.16</version>
<version>2.5.19</version>
</parent>
<artifactId>struts2-junit-plugin</artifactId>
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>2.5.16</version>
<version>2.5.19</version>
</parent>
<artifactId>struts2-osgi-plugin</artifactId>
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>2.5.16</version>
<version>2.5.19</version>
</parent>
<artifactId>struts2-oval-plugin</artifactId>
@@ -28,6 +28,8 @@ import java.util.Arrays;
import java.util.List;
import java.util.Map;
import junit.framework.AssertionFailedError;
public class OValValidationInterceptorTest extends XWorkTestCase {
public void testSimpleFieldsXML() throws Exception {
ActionProxy baseActionProxy = actionProxyFactory.createActionProxy("oval", "simpleFieldsXML", null, null);
@@ -283,7 +285,18 @@ public class OValValidationInterceptorTest extends XWorkTestCase {
assertEquals(5, fieldErrors.size()); // 5: as there will be field errors for 'model' and 'address' themselves
assertValue(fieldErrors, "name", Arrays.asList("name cannot be null"));
assertValue(fieldErrors, "email", Arrays.asList("email cannot be null"));
assertValue(fieldErrors, "address.street", Arrays.asList("street cannot be smaller than 7 characters"));
try {
// Oval version <= 1.40 validation error for invalid data reports: "net.sf.oval.constraint.AssertValid.violated".
assertValue(fieldErrors, "address", Arrays.asList("net.sf.oval.constraint.AssertValid.violated"));
// Oval version <= 1.40 validation error for minimum length reports: "street cannot be smaller than 7 characters".
assertValue(fieldErrors, "address.street", Arrays.asList("street cannot be smaller than 7 characters"));
}
catch (AssertionFailedError afe) {
// Oval version >= 1.50 validation error for invalid data reports: "address is invalid".
assertValue(fieldErrors, "address", Arrays.asList("address is invalid"));
// Oval version >= 1.50 validation error for minimum length reports: "street cannot be shorter than 7 characters".
assertValue(fieldErrors, "address.street", Arrays.asList("street cannot be shorter than 7 characters"));
}
}
@@ -300,7 +313,19 @@ public class OValValidationInterceptorTest extends XWorkTestCase {
assertEquals(5, fieldErrors.size()); // 5: as there will be field errors for 'person' and 'person.address' themselves
assertValue(fieldErrors, "person.name", Arrays.asList("name cannot be null"));
assertValue(fieldErrors, "person.email", Arrays.asList("email cannot be null"));
assertValue(fieldErrors, "person.address.street", Arrays.asList("street cannot be smaller than 7 characters"));
try {
// Oval version <= 1.40 validation error for invalid data reports: "net.sf.oval.constraint.AssertValid.violated".
assertValue(fieldErrors, "person.address", Arrays.asList("net.sf.oval.constraint.AssertValid.violated"));
// Oval version <= 1.40 validation error for minimum length reports: "street cannot be smaller than 7 characters".
assertValue(fieldErrors, "person.address.street", Arrays.asList("street cannot be smaller than 7 characters"));
}
catch (AssertionFailedError afe) {
// Oval version >= 1.50 validation error for invalid data reports: "address is invalid".
assertValue(fieldErrors, "person.address", Arrays.asList("address is invalid"));
// Oval version >= 1.50 validation error for minimum length reports: "street cannot be shorter than 7 characters".
assertValue(fieldErrors, "person.address.street", Arrays.asList("street cannot be shorter than 7 characters"));
}
}
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>2.5.16</version>
<version>2.5.19</version>
</parent>
<artifactId>struts2-pell-multipart-plugin</artifactId>
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>2.5.16</version>
<version>2.5.19</version>
</parent>
<artifactId>struts2-plexus-plugin</artifactId>

Some files were not shown because too many files have changed in this diff Show More