Compare commits

..

80 Commits

Author SHA1 Message Date
Lukasz Lenart 22573f8de8 [maven-release-plugin] prepare release STRUTS_2_3_22 2015-03-19 07:11:15 +01:00
Lukasz Lenart 4f0f7d1384 Adds additional use case to check access to values of int type 2015-03-07 07:39:44 +01:00
Lukasz Lenart 54c6423484 WW-4457 Uses dedicated type to match content type of uploaded files 2015-03-06 22:34:35 +01:00
Lukasz Lenart 5665dd52b5 WW-4468 Switched to buildError on file limit excided 2015-03-06 21:40:10 +01:00
Lukasz Lenart a1d277fac5 WW-4467 disableRequestAttributeValueStackLookup applied
to MultiPartRequestWrapper
2015-03-06 21:20:08 +01:00
Lukasz Lenart 4ad023207f WW-4473 Adds support for title attribute in SubmitHandler 2015-03-06 21:07:17 +01:00
Lukasz Lenart 66248a80e3 WW-4427 adds complete fix 2015-02-17 07:49:15 +01:00
Lukasz Lenart c5867e2ea2 WW-4465 Ignores statusCode parameter when building redirect url 2015-02-17 07:38:13 +01:00
cnenning fbe7d5138e made bufferSize optional, see WW-4466 2015-02-16 14:24:55 +01:00
Przemek Bruski e0d72397c2 WW-4427 - Converters are no longer applied to values coming from the context on error path 2015-02-15 10:40:13 +01:00
Aleksandr Mashchenko 76ea79f38a Handle default (unnamed) package security check 2015-02-04 22:57:55 +02:00
Lukasz Lenart 312a2717cf WW-4452 Solves problem with using -1 as headerKey 2015-02-02 21:22:42 +01:00
Lukasz Lenart 46b28e0b63 WW-4446 Adds wrapper around Dispatcher in tests to avoid overwhelming
warnings
2015-02-02 10:04:40 +01:00
Lukasz Lenart 5e74fcd946 WW-4454 Adds dedicated hidden.ftl template to avoid problems with layout 2015-02-01 15:53:38 +01:00
Lukasz Lenart cd0d8de67a WW-4453 Reports missing value 2015-01-27 09:00:00 +01:00
Lukasz Lenart acef492390 WW-4448 Replaces spaces with encoded value 2015-01-21 09:07:07 +01:00
Lukasz Lenart d9973fee06 WW-4449 Extends JSONWriter to support Javassist 3.18.1 and Hibernate 4.3.7 2015-01-21 08:54:09 +01:00
Lukasz Lenart 0f44e11cd1 WW-4448 Strips params and replaces spaces 2015-01-21 08:46:49 +01:00
Lukasz Lenart e3428c5fe5 Extracts string into constant 2015-01-21 08:15:41 +01:00
aronshen b888275803 change findBaseAccessor method
in hibernate4.3.7,because javassist3.18.1's class name generate rule is '_$$_jvst'+...
2015-01-20 11:54:10 +08:00
Lukasz Lenart 2433789379 WW-4447 Reverts some changes introduced by WW-4297
Resetting 'label' attribute can block user if they would like to
develop their own hidden.ftl template
2015-01-14 16:15:17 +01:00
Lukasz Lenart 0b49c2c2c9 Starting new development cycle 2014-12-31 18:13:55 +01:00
Lukasz Lenart f4b4ffbda1 Version 2.3.21 pushed for test 2014-12-31 18:13:31 +01:00
Lukasz Lenart 22cbf40fc2 [maven-release-plugin] prepare for next development iteration 2014-12-31 14:53:22 +01:00
Lukasz Lenart a40e9a90bf [maven-release-plugin] prepare release STRUTS_2_3_21 2014-12-31 14:53:04 +01:00
Lukasz Lenart 9bca437b9a WW-4434 Adds basic version of missing ftl 2014-12-30 20:47:46 +01:00
Lukasz Lenart 64234907c6 WW-4055 Reverts commit dfb2bd3 2014-12-30 09:23:23 +01:00
Lukasz Lenart da4a22078a WW-4413 Improves JSON interceptor to handle JSON arrays 2014-12-29 11:29:08 +01:00
Lukasz Lenart 1f333997fc WW-4406 Fixes problem with failing test under different Locale 2014-12-29 11:20:55 +01:00
Lukasz Lenart f4918d1e2f WW-4429 Adds additional tests to cover unsecure access 2014-12-26 20:49:26 +01:00
Lukasz Lenart 095018c3a0 WW-4429 Simplifies isClassExcluded interface 2014-12-26 20:48:44 +01:00
Lukasz Lenart f1c04d6f4d WW-4424 Fixes log message to properly report missing property 2014-12-23 22:18:30 +01:00
Lukasz Lenart ddac7f3a54 WW-4432 Fixes access to javax.servlet package 2014-12-23 22:07:51 +01:00
Lukasz Lenart 2bea99e96b WW-4436 Fixes NPE and uses String.valueOf() instead of .toString() 2014-12-23 21:54:01 +01:00
Lukasz Lenart 29de8687dd WW-4419 Fixes NPE when performing async request 2014-12-23 21:49:21 +01:00
Lukasz Lenart 2b150d8775 Adds logging and proper header with licence 2014-12-23 21:48:43 +01:00
Lukasz Lenart 532841d40f WW-4429 Fixes support for accessing static methods 2014-12-23 21:29:30 +01:00
Lukasz Lenart a35c3ef4f6 WW-4416 Adds support to clear cache under Tomcat 8 2014-12-23 17:04:26 +01:00
Lukasz Lenart 60db1aadb0 WW-4427 Converts value retrieved from context 2014-12-23 16:09:14 +01:00
Lukasz Lenart 3a0350f0dc Adds additional use case when value from conext is null 2014-12-23 16:07:58 +01:00
Lukasz Lenart 40822d67f5 WW-4437 Fixes problem with accepted params 2014-12-23 13:29:17 +01:00
Lukasz Lenart 4964b74797 WW-4430 Resolves problem with missing setter and JasperException 2014-12-23 10:55:00 +01:00
Lukasz Lenart a46b803999 WW-4441 Fixes memory leak in CDI factory 2014-12-23 10:29:16 +01:00
Lukasz Lenart 3bf67283e7 WW-4435 Allows use different versions of ASM 2014-12-23 09:51:04 +01:00
Lukasz Lenart 22fbc800f2 Adds basic readme 2014-12-23 09:35:31 +01:00
Lukasz Lenart b11bb2574b Updates docs url 2014-12-23 08:19:28 +01:00
Lukasz Lenart adc2d5ccf9 Adds fixed Jetty version 2014-12-23 07:45:58 +01:00
Lukasz Lenart 73644d2ccf Merge branch 'develop' into WW-4435 2014-12-21 20:48:51 +01:00
Lukasz Lenart 702738693c Adds additional use cases and fixes some minor issues 2014-12-21 20:46:40 +01:00
Lukasz Lenart 43679fc3f4 Adds some JavaDocs 2014-12-20 21:52:01 +01:00
Lukasz Lenart 463a90e8b7 Adds Java8 specific ClassFinder with injection 2014-12-20 21:49:36 +01:00
Lukasz Lenart a7cf429479 Adds site defintion 2014-12-20 21:47:25 +01:00
Lukasz Lenart 99e53d8642 Adds required legal files 2014-12-20 21:46:42 +01:00
Lukasz Lenart a1941a8528 Adds factory to allow create different versions of ClassFinder 2014-12-20 21:46:25 +01:00
Lukasz Lenart 3ce21ac483 Extracts interface with default implementation 2014-12-20 21:45:30 +01:00
Lukasz Lenart 6471eec0ab Defines new java8-plugin to support Java 8 2014-12-20 21:44:43 +01:00
Lukasz Lenart 6774e840c8 Reverts to old version of ASM and adds ASM 5 as well 2014-12-20 21:44:18 +01:00
Lukasz Lenart 61ab8137eb Adds test cases to cover three use cases with flow of exceptions 2014-12-20 09:02:56 +01:00
Lukasz Lenart bf7714f7ae Improves flow of exceptions and missing action method 2014-12-20 09:02:28 +01:00
Lukasz Lenart 3288096c2b Adds proper deprecation note 2014-12-20 08:55:55 +01:00
Lukasz Lenart 5551a9bb60 Adds jenv specific file 2014-12-20 08:54:31 +01:00
Przemek Bruski debaaa2443 WW-4427 - cleaned up UT 2014-12-16 17:07:10 +01:00
Przemek Bruski 6a58778399 WW-4427 - inject the converter instead of getting it directly 2014-12-16 16:58:38 +01:00
Przemek Bruski 6834b78fe9 WW-4427 - Converters are no longer applied to values coming from the context - fix and UT 2014-12-09 17:17:15 +01:00
Lukasz Lenart adb7b8c73f Updates link which points to Confluence docs 2014-12-05 11:44:02 +01:00
Lukasz Lenart 5f2898eadf Cleans up Maven generated website 2014-12-02 12:41:06 +01:00
Lukasz Lenart ae4e3d116b Reformats source code 2014-11-21 21:55:40 +01:00
Lukasz Lenart 3e0e3836eb Merge branch 'master' into develop 2014-11-21 21:53:43 +01:00
Lukasz Lenart 2886a30917 Merge branch 'release/2.3.20' 2014-11-21 21:53:36 +01:00
Lukasz Lenart 5078537ff6 [maven-release-plugin] prepare for next development iteration 2014-11-21 19:30:20 +01:00
Lukasz Lenart 0320310406 [maven-release-plugin] prepare release STRUTS_2_3_20 2014-11-21 19:30:08 +01:00
Lukasz Lenart 1f301038a7 Uses better random generator 2014-11-21 19:21:35 +01:00
Lukasz Lenart e1025a207d WW-4391 reverts changes as this breaks WW-4420 2014-11-17 11:39:38 +01:00
Lukasz Lenart 77c76dc691 Merge branch 'master' into develop 2014-11-17 11:31:58 +01:00
Lukasz Lenart aebdad9f6c Merge branch 'release/2.3.19' 2014-11-17 11:31:52 +01:00
Lukasz Lenart f7f4915bd3 [maven-release-plugin] prepare for next development iteration 2014-11-14 08:31:27 +01:00
zhouyanming 7bce8ef6a8 Defend for NPE when performing async request
when I combined spring async mvc with struts2 sitemesh plugin, It will throw NPE

java.lang.NullPointerException
	at org.apache.struts2.ServletActionContext.getRequest(ServletActionContext.java:112)
	at org.apache.struts2.sitemesh.StrutsSiteMeshFactory.isInsideActionTag(StrutsSiteMeshFactory.java:25)
	at org.apache.struts2.sitemesh.StrutsSiteMeshFactory.shouldParsePage(StrutsSiteMeshFactory.java:21)
	at com.opensymphony.sitemesh.compatability.PageParser2ContentProcessor.handles(PageParser2ContentProcessor.java:45)
	at com.opensymphony.sitemesh.webapp.ContentBufferingResponse$1.shouldParsePage(ContentBufferingResponse.java:29)
	at com.opensymphony.module.sitemesh.filter.PageResponseWrapper.setContentType(PageResponseWrapper.java:63)
	at com.opensymphony.sitemesh.webapp.ContentBufferingResponse$2.setContentType(ContentBufferingResponse.java:39)
	at com.opensymphony.module.sitemesh.filter.PageResponseWrapper.addHeader(PageResponseWrapper.java:135)
	at javax.servlet.http.HttpServletResponseWrapper.addHeader(HttpServletResponseWrapper.java:173)
	at org.springframework.http.server.ServletServerHttpResponse.writeHeaders(ServletServerHttpResponse.java:103)
	at org.springframework.http.server.ServletServerHttpResponse.getBody(ServletServerHttpResponse.java:83)
	at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:217)
	at org.springframework.http.converter.AbstractHttpMessageConverter.write(AbstractHttpMessageConverter.java:208)
	at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:161)
	at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:101)
	at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:199)
	at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:71)
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:128)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:781)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:721)
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:748)
	at org.apache.catalina.core.ApplicationDispatcher.doDispatch(ApplicationDispatcher.java:659)
	at org.apache.catalina.core.ApplicationDispatcher.dispatch(ApplicationDispatcher.java:625)
	at org.apache.catalina.core.AsyncContextImpl$1.run(AsyncContextImpl.java:239)
	at org.apache.catalina.core.AsyncContextImpl.doInternalDispatch(AsyncContextImpl.java:382)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:215)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
	at org.apache.catalina.connector.CoyoteAdapter.asyncDispatch(CoyoteAdapter.java:299)
	at org.apache.coyote.http11.AbstractHttp11Processor.asyncDispatch(AbstractHttp11Processor.java:1652)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:314)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:745)
2014-11-13 16:06:00 +08:00
Michael Stevens 6291fa920d Fix Memory leak in CDI plugin
The CDI plugin was using a single 'CreationalContext' for all beans created by the CDIObjectFactory. This is incorrect and the size of the 'dependentInstances' (in the WELD implementation) grows indefinately with no beans being removed. 
Fix is to use a new 'CreationalContext' for every bean created. In our tests with WELD this does not effect the applications performance. Idealy a single 'CreationalContext' should be created for the request lifecycle. However the struts ObjectFactory API does not appear to provide any information able the lifecycle.
2014-11-12 13:35:15 +01:00
Aleksandr Mashchenko 61cffe68fe improved interceptor that accepts and maps JSON array 2014-10-13 20:07:07 +03:00
Aleksandr Mashchenko 6e95cf5bf7 use locale from action context 2014-09-27 17:50:19 +03:00
158 changed files with 4690 additions and 1536 deletions
+3
View File
@@ -15,6 +15,9 @@
# Scripts
*.sh
# jenv
.java-version
# Maven
core/target
xwork-core/target
+1 -1
View File
@@ -26,7 +26,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-apps</artifactId>
<version>2.3.19</version>
<version>2.3.22</version>
</parent>
<artifactId>struts2-blank</artifactId>
+1 -1
View File
@@ -26,7 +26,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-apps</artifactId>
<version>2.3.19</version>
<version>2.3.22</version>
</parent>
<artifactId>struts2-jboss-blank</artifactId>
+1 -1
View File
@@ -26,7 +26,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-apps</artifactId>
<version>2.3.19</version>
<version>2.3.22</version>
</parent>
<artifactId>struts2-mailreader</artifactId>
+9 -116
View File
@@ -26,7 +26,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-parent</artifactId>
<version>2.3.19</version>
<version>2.3.22</version>
</parent>
<artifactId>struts2-apps</artifactId>
<packaging>pom</packaging>
@@ -40,120 +40,6 @@
<module>rest-showcase</module>
</modules>
<profiles>
<profile>
<id>hostedqa</id>
<dependencies>
<dependency>
<groupId>com.hostedqa</groupId>
<artifactId>hostedqa-remote-ant</artifactId>
<version>1.7</version>
<scope>test</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<id>codehaus</id>
<name>codehaus</name>
<url>http://repository.codehaus.org</url>
</repository>
<repository>
<id>maven-hostedqa</id>
<name>maven-hostedqa</name>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
<checksumPolicy>ignore</checksumPolicy>
</snapshots>
<releases>
<enabled>true</enabled>
</releases>
<url>http://maven.hostedqa.com</url>
</repository>
</repositories>
<build>
<resources>
<!-- Include resources under src/main/java in WEB-INF/classes -->
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<groupId>org.apache.maven.plugins</groupId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<taskdef resource="hostedqatasks" classpathref="maven.plugin.classpath" />
<upload file="${project.build.directory}/${project.build.finalName}.war" account="struts" email="${email}" password="${password}" resourceId="${resourceId}" />
<playsuite suiteId="${suiteId}" clientConfigs="${clientConfigs}" appConfigs="${appConfigs}" account="struts" email="${email}" password="${password}" />
</tasks>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.hostedqa</groupId>
<artifactId>hostedqa-remote-ant</artifactId>
<version>1.7</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>release</id>
<activation>
<property>
<name>release</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<inherited>true</inherited>
<groupId>org.codehaus.mojo</groupId>
<artifactId>rat-maven-plugin</artifactId>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>check</goal>
</goals>
<configuration>
<addDefaultLicenseMatchers>false</addDefaultLicenseMatchers>
<licenseMatchers>
<classNames>
<className>rat.analysis.license.ApacheSoftwareLicense20</className>
</classNames>
</licenseMatchers>
<includes>
<include>pom.xml</include>
</includes>
<excludes>
<exclude>src/**</exclude>
</excludes>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<build>
<plugins>
<!-- Include source code under WEB-INF/src/java -->
@@ -196,6 +82,14 @@
<warSourceExcludes>WEB-INF/classes/LICENSE.txt,WEB-INF/classes/NOTICE.txt</warSourceExcludes>
</configuration>
</plugin>
<plugin>
<artifactId>maven-site-plugin</artifactId>
<configuration>
<skip>true</skip>
<skipDeploy>true</skipDeploy>
<generateReports>false</generateReports>
</configuration>
</plugin>
</plugins>
<finalName>${project.artifactId}</finalName>
@@ -203,7 +97,6 @@
</build>
<dependencies>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
+3 -2
View File
@@ -26,7 +26,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-apps</artifactId>
<version>2.3.19</version>
<version>2.3.22</version>
</parent>
<artifactId>struts2-portlet</artifactId>
@@ -62,6 +62,7 @@
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.26</version>
<configuration>
<webXml>${project.build.directory}/pluto-resources/web.xml</webXml>
<webDefaultXml>src/main/webapp/WEB-INF/jetty-pluto-web-default.xml</webDefaultXml>
@@ -79,7 +80,7 @@
<dependency>
<groupId>com.bekk.boss</groupId>
<artifactId>maven-jetty-pluto-embedded</artifactId>
<version>1.0</version>
<version>1.0.1</version>
</dependency>
</dependencies>
</profile>
+2 -2
View File
@@ -26,12 +26,12 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-apps</artifactId>
<version>2.3.19</version>
<version>2.3.22</version>
</parent>
<artifactId>struts2-rest-showcase</artifactId>
<packaging>war</packaging>
<version>2.3.19</version>
<version>2.3.22</version>
<name>Struts 2 Rest Showcase Webapp</name>
<description>Struts 2 Rest Showcase Example</description>
+1 -1
View File
@@ -26,7 +26,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-apps</artifactId>
<version>2.3.19</version>
<version>2.3.22</version>
</parent>
<artifactId>struts2-showcase</artifactId>
+15 -1
View File
@@ -26,7 +26,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-parent</artifactId>
<version>2.3.19</version>
<version>2.3.22</version>
</parent>
<artifactId>struts2-archetypes</artifactId>
@@ -46,4 +46,18 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-site-plugin</artifactId>
<configuration>
<skip>true</skip>
<skipDeploy>true</skipDeploy>
<generateReports>false</generateReports>
</configuration>
</plugin>
</plugins>
</build>
</project>
@@ -2,7 +2,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-archetypes</artifactId>
<version>2.3.19</version>
<version>2.3.22</version>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -3,7 +3,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-archetypes</artifactId>
<version>2.3.19</version>
<version>2.3.22</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -2,7 +2,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-archetypes</artifactId>
<version>2.3.19</version>
<version>2.3.22</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -2,7 +2,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-archetypes</artifactId>
<version>2.3.19</version>
<version>2.3.22</version>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -2,7 +2,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-archetypes</artifactId>
<version>2.3.19</version>
<version>2.3.22</version>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -2,7 +2,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-archetypes</artifactId>
<version>2.3.19</version>
<version>2.3.22</version>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-archetypes</artifactId>
<version>2.3.19</version>
<version>2.3.22</version>
</parent>
<modelVersion>4.0.0</modelVersion>
+4 -2
View File
@@ -3,7 +3,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-parent</artifactId>
<version>2.3.19</version>
<version>2.3.22</version>
</parent>
<artifactId>struts2-assembly</artifactId>
@@ -16,6 +16,8 @@
<plugin>
<artifactId>maven-site-plugin</artifactId>
<configuration>
<skip>true</skip>
<skipDeploy>true</skipDeploy>
<generateReports>false</generateReports>
</configuration>
</plugin>
@@ -100,7 +102,7 @@
<arg value="--directory-prefix=${project.build.directory}/cwiki" />
<arg value="--no-check-certificate" />
<arg value="-r" />
<arg value="http://struts.apache.org/development/2.x/docs/" />
<arg value="http://struts.apache.org/docs/" />
</exec>
<delete>
<fileset dir="${project.build.directory}/cwiki/" includes="**/index.*" />
+17 -4
View File
@@ -6,10 +6,11 @@
<groupId>org.apache.struts</groupId>
<artifactId>struts-master</artifactId>
<version>9</version>
<relativePath>../struts-master</relativePath>
</parent>
<artifactId>struts2-bom</artifactId>
<version>2.3.19</version>
<version>2.3.22</version>
<packaging>pom</packaging>
<name>Struts 2 Bill of Materials</name>
@@ -24,9 +25,22 @@
</licenses>
<properties>
<struts-version.version>2.3.19</struts-version.version>
<struts-version.version>2.3.22</struts-version.version>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-site-plugin</artifactId>
<configuration>
<skip>true</skip>
<skipDeploy>true</skipDeploy>
<generateReports>false</generateReports>
</configuration>
</plugin>
</plugins>
</build>
<dependencyManagement>
<dependencies>
<dependency>
@@ -182,8 +196,7 @@
</dependencies>
</dependencyManagement>
<scm>
<tag>STRUTS_2_3_19</tag>
<tag>STRUTS_2_3_22</tag>
</scm>
</project>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-osgi-bundles</artifactId>
<version>2.3.19</version>
<version>2.3.22</version>
</parent>
<artifactId>struts2-osgi-admin-bundle</artifactId>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-osgi-bundles</artifactId>
<version>2.3.19</version>
<version>2.3.22</version>
</parent>
<artifactId>struts2-osgi-demo-bundle</artifactId>
+1 -1
View File
@@ -26,7 +26,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-parent</artifactId>
<version>2.3.19</version>
<version>2.3.22</version>
</parent>
<artifactId>struts2-osgi-bundles</artifactId>
+1 -23
View File
@@ -26,7 +26,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-parent</artifactId>
<version>2.3.19</version>
<version>2.3.22</version>
</parent>
<artifactId>struts2-core</artifactId>
<packaging>jar</packaging>
@@ -76,28 +76,6 @@
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>rat-maven-plugin</artifactId>
<configuration>
<includes>
<include>pom.xml</include>
<include>src/**</include>
</includes>
<excludes>
<exclude>src/test/resources/org/apache/struts2/views/jsp/ui/*</exclude>
<exclude>src/main/resources/org/apache/struts2/static/domTT.js</exclude>
<exclude>src/test/resources/org/apache/struts2/interceptor/validation/*</exclude>
<exclude>src/site/resources/tags/**</exclude>
<exclude>src/main/resources/*LICENSE.txt</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</reporting>
<profiles>
<profile>
<id>alljars</id>
@@ -299,4 +299,6 @@ public final class StrutsConstants {
public static final String STRUTS_ADDITIONAL_EXCLUDED_PATTERNS = "struts.additional.excludedPatterns";
public static final String STRUTS_ADDITIONAL_ACCEPTED_PATTERNS = "struts.additional.acceptedPatterns";
public static final String STRUTS_CONTENT_TYPE_MATCHER = "struts.contentTypeMatcher";
}
@@ -69,6 +69,7 @@ public class Component {
*/
protected static ConcurrentMap<Class<?>, Collection<String>> standardAttributesMap = new ConcurrentHashMap<Class<?>, Collection<String>>();
protected boolean devMode = false;
protected ValueStack stack;
protected Map parameters;
protected ActionMapper actionMapper;
@@ -97,7 +98,12 @@ public class Component {
return name.substring(dot + 1).toLowerCase();
}
@Inject(value = StrutsConstants.STRUTS_DEVMODE, required = false)
public void setDevMode(String devMode) {
this.devMode = Boolean.parseBoolean(devMode);
}
@Inject
public void setActionMapper(ActionMapper mapper) {
this.actionMapper = mapper;
@@ -285,6 +285,14 @@ public class Date extends ContextBean {
date = (java.util.Date) dateObject;
} else if(dateObject instanceof Calendar){
date = ((Calendar) dateObject).getTime();
} else {
if (devMode) {
LOG.error("Expression [#0] passed to <s:date/> tag which was evaluated to [#1](#2) isn't instance of java.util.Date nor java.util.Calendar!",
name, dateObject, (dateObject != null ? dateObject.getClass() : "null"));
} else {
LOG.debug("Expression [#0] passed to <s:date/> tag which was evaluated to [#1](#2) isn't instance of java.util.Date nor java.util.Calendar!",
name, dateObject, (dateObject != null ? dateObject.getClass() : "null"));
}
}
} catch (Exception e) {
LOG.error("Could not convert object with key '#0' to a java.util.Date instance", name);
@@ -66,10 +66,4 @@ public class Hidden extends UIBean {
return TEMPLATE;
}
@Override
public void evaluateParams() {
super.evaluateParams();
label = null;
addParameter("label", null);
}
}
@@ -67,6 +67,7 @@ import org.apache.struts2.dispatcher.DispatcherErrorHandler;
import org.apache.struts2.dispatcher.StaticContentLoader;
import org.apache.struts2.dispatcher.mapper.ActionMapper;
import org.apache.struts2.dispatcher.multipart.MultiPartRequest;
import org.apache.struts2.util.ContentTypeMatcher;
import org.apache.struts2.views.freemarker.FreemarkerManager;
import org.apache.struts2.views.util.UrlHelper;
import org.apache.struts2.views.velocity.VelocityManager;
@@ -327,6 +328,12 @@ import java.util.StringTokenizer;
* <td>request</td>
* <td>Used across different interceptors to check if given string matches one of the accepted patterns</td>
* </tr>
* <tr>
* <td>org.apache.struts2.util.ContentTypeMatcher</td>
* <td>struts.contentTypeMatcher</td>
* <td>singleton</td>
* <td>Matches content type of uploaded files (since 2.3.22)</td>
* </tr>
* </table>
*
* <!-- END SNIPPET: extensionPoints -->
@@ -391,6 +398,7 @@ public class DefaultBeanSelectionProvider extends AbstractBeanSelectionProvider
alias(ReflectionProvider.class, StrutsConstants.STRUTS_REFLECTIONPROVIDER, builder, props);
alias(ReflectionContextFactory.class, StrutsConstants.STRUTS_REFLECTIONCONTEXTFACTORY, builder, props);
alias(PatternMatcher.class, StrutsConstants.STRUTS_PATTERNMATCHER, builder, props);
alias(ContentTypeMatcher.class, StrutsConstants.STRUTS_CONTENT_TYPE_MATCHER, builder, props);
alias(StaticContentLoader.class, StrutsConstants.STRUTS_STATIC_CONTENT_LOADER, builder, props);
alias(UnknownHandlerManager.class, StrutsConstants.STRUTS_UNKNOWN_HANDLER_MANAGER, builder, props);
alias(UrlHelper.class, StrutsConstants.STRUTS_URL_HELPER, builder, props);
@@ -835,7 +835,7 @@ public class Dispatcher {
if (content_type != null && content_type.contains("multipart/form-data")) {
MultiPartRequest mpr = getMultiPartRequest();
LocaleProvider provider = getContainer().getInstance(LocaleProvider.class);
request = new MultiPartRequestWrapper(mpr, request, getSaveDir(), provider);
request = new MultiPartRequestWrapper(mpr, request, getSaveDir(), provider, disableRequestAttributeValueStackLookup);
} else {
request = new StrutsRequestWrapper(request, disableRequestAttributeValueStackLookup);
}
@@ -210,7 +210,18 @@ public class ServletActionRedirectResult extends ServletRedirectResult implement
}
protected List<String> getProhibitedResultParams() {
return Arrays.asList(DEFAULT_PARAM, "namespace", "method", "encode", "parse", "location", "prependServletContext", "suppressEmptyParameters", "anchor");
return Arrays.asList(
DEFAULT_PARAM,
"namespace",
"method",
"encode",
"parse",
"location",
"prependServletContext",
"suppressEmptyParameters",
"anchor",
"statusCode"
);
}
}
@@ -272,7 +272,11 @@ public class ServletRedirectResult extends StrutsResultSupport implements Reflec
*/
protected boolean isPathUrl(String url) {
try {
URI uri = URI.create(url);
String rawUrl = url;
if (url.contains("?")) {
rawUrl = url.substring(0, url.indexOf("?"));
}
URI uri = URI.create(rawUrl.replaceAll(" ", "%20"));
if (uri.isAbsolute()) {
URL validUrl = uri.toURL();
if (LOG.isDebugEnabled()) {
@@ -110,6 +110,9 @@ public abstract class StrutsResultSupport implements Result, StrutsStatics {
/** The default parameter */
public static final String DEFAULT_PARAM = "location";
/** use UTF-8 as this is the recommended encoding by W3C to avoid incompatibilities. */
public static final String DEFAULT_URL_ENCODING = "UTF-8";
private boolean parse;
private boolean encode;
private String location;
@@ -240,9 +243,7 @@ public abstract class StrutsResultSupport implements Result, StrutsStatics {
if (encode) {
if (parsedValue != null) {
try {
// use UTF-8 as this is the recommended encoding by W3C to
// avoid incompatibilities.
return URLEncoder.encode(parsedValue, "UTF-8");
return URLEncoder.encode(parsedValue, DEFAULT_URL_ENCODING);
}
catch(UnsupportedEncodingException e) {
if (LOG.isWarnEnabled()) {
@@ -97,7 +97,7 @@ public class JakartaStreamMultiPartRequest implements MultiPartRequest {
*
* @param bufferSize
*/
@Inject(StrutsConstants.STRUTS_MULTIPART_BUFFERSIZE)
@Inject(value = StrutsConstants.STRUTS_MULTIPART_BUFFERSIZE, required = false)
public void setBufferSize(String bufferSize) {
this.bufferSize = Integer.parseInt(bufferSize);
}
@@ -357,7 +357,7 @@ public class JakartaStreamMultiPartRequest implements MultiPartRequest {
private void addFileSkippedError(String fileName, HttpServletRequest request) {
String exceptionMessage = "Skipped file " + fileName + "; request size limit exceeded.";
FileSizeLimitExceededException exception = new FileUploadBase.FileSizeLimitExceededException(exceptionMessage, getRequestSize(request), maxSize);
String message = buildMessage(exception, new Object[]{fileName, getRequestSize(request), maxSize});
String message = buildErrorMessage(exception, new Object[]{fileName, getRequestSize(request), maxSize});
if (!errors.contains(message))
errors.add(message);
}
@@ -21,6 +21,7 @@
package org.apache.struts2.dispatcher.multipart;
import com.opensymphony.xwork2.DefaultLocaleProvider;
import com.opensymphony.xwork2.LocaleProvider;
import com.opensymphony.xwork2.util.LocalizedTextUtil;
import com.opensymphony.xwork2.util.logging.Logger;
@@ -71,8 +72,10 @@ public class MultiPartRequestWrapper extends StrutsRequestWrapper {
* @param saveDir Target directory for any files that we save
* @param provider
*/
public MultiPartRequestWrapper(MultiPartRequest multiPartRequest, HttpServletRequest request, String saveDir, LocaleProvider provider) {
super(request);
public MultiPartRequestWrapper(MultiPartRequest multiPartRequest, HttpServletRequest request,
String saveDir, LocaleProvider provider,
boolean disableRequestAttributeValueStackLookup) {
super(request, disableRequestAttributeValueStackLookup);
errors = new ArrayList<String>();
multi = multiPartRequest;
defaultLocale = provider.getLocale();
@@ -90,6 +93,10 @@ public class MultiPartRequestWrapper extends StrutsRequestWrapper {
}
}
public MultiPartRequestWrapper(MultiPartRequest multiPartRequest, HttpServletRequest request, String saveDir, LocaleProvider provider) {
this(multiPartRequest, request, saveDir, provider, false);
}
protected void setLocale(HttpServletRequest request) {
if (defaultLocale == null) {
defaultLocale = request.getLocale();
@@ -25,6 +25,7 @@ import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.inject.Inject;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import com.opensymphony.xwork2.security.AcceptedPatternsChecker;
import com.opensymphony.xwork2.security.ExcludedPatternsChecker;
import com.opensymphony.xwork2.util.TextParseUtil;
import com.opensymphony.xwork2.util.ValueStack;
@@ -37,7 +38,6 @@ import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
/**
* <!-- START SNIPPET: description -->
@@ -174,16 +174,20 @@ public class CookieInterceptor extends AbstractInterceptor {
private Set<String> cookiesNameSet = Collections.emptySet();
private Set<String> cookiesValueSet = Collections.emptySet();
// Allowed names of cookies
private Pattern acceptedPattern = Pattern.compile(ACCEPTED_PATTERN, Pattern.CASE_INSENSITIVE);
private ExcludedPatternsChecker excludedPatternsChecker;
private AcceptedPatternsChecker acceptedPatternsChecker;
@Inject
public void setExcludedPatternsChecker(ExcludedPatternsChecker excludedPatternsChecker) {
this.excludedPatternsChecker = excludedPatternsChecker;
}
@Inject
public void setAcceptedPatternsChecker(AcceptedPatternsChecker acceptedPatternsChecker) {
this.acceptedPatternsChecker = acceptedPatternsChecker;
this.acceptedPatternsChecker.setAcceptedPatterns(ACCEPTED_PATTERN);
}
/**
* Set the <code>cookiesName</code> which if matched will allow the cookie
* to be injected into action, could be comma-separated string.
@@ -208,12 +212,13 @@ public class CookieInterceptor extends AbstractInterceptor {
}
/**
* Set the <code>acceptCookieNames</code> pattern of allowed names of cookies to protect against remote command execution vulnerability
* Set the <code>acceptCookieNames</code> pattern of allowed names of cookies
* to protect against remote command execution vulnerability.
*
* @param pattern used to check cookie name against
* @param commaDelimitedPattern is used to check cookie name against, can set of comma delimited patterns
*/
public void setAcceptCookieNames(String pattern) {
acceptedPattern = Pattern.compile(pattern);
public void setAcceptCookieNames(String commaDelimitedPattern) {
acceptedPatternsChecker.setAcceptedPatterns(commaDelimitedPattern);
}
public String intercept(ActionInvocation invocation) throws Exception {
@@ -280,17 +285,17 @@ public class CookieInterceptor extends AbstractInterceptor {
* @return true|false
*/
protected boolean isAccepted(String name) {
boolean matches = acceptedPattern.matcher(name).matches();
if (matches) {
AcceptedPatternsChecker.IsAccepted accepted = acceptedPatternsChecker.isAccepted(name);
if (accepted.isAccepted()) {
if (LOG.isTraceEnabled()) {
LOG.trace("Cookie [#0] matches acceptedPattern [#1]", name, ACCEPTED_PATTERN);
}
} else {
if (LOG.isTraceEnabled()) {
LOG.trace("Cookie [#0] doesn't match acceptedPattern [#1]", name, ACCEPTED_PATTERN);
LOG.trace("Cookie [#0] matches acceptedPattern [#1]", name, accepted.getAcceptedPattern());
}
return true;
}
return matches;
if (LOG.isTraceEnabled()) {
LOG.trace("Cookie [#0] doesn't match acceptedPattern [#1]", name, accepted.getAcceptedPattern());
}
return false;
}
/**
@@ -31,12 +31,12 @@ import com.opensymphony.xwork2.ValidationAware;
import com.opensymphony.xwork2.inject.Container;
import com.opensymphony.xwork2.inject.Inject;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import com.opensymphony.xwork2.util.PatternMatcher;
import com.opensymphony.xwork2.util.TextParseUtil;
import com.opensymphony.xwork2.util.logging.Logger;
import com.opensymphony.xwork2.util.logging.LoggerFactory;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper;
import org.apache.struts2.util.ContentTypeMatcher;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
@@ -195,11 +195,11 @@ public class FileUploadInterceptor extends AbstractInterceptor {
protected Set<String> allowedTypesSet = Collections.emptySet();
protected Set<String> allowedExtensionsSet = Collections.emptySet();
private PatternMatcher matcher;
private ContentTypeMatcher matcher;
private Container container;
@Inject
public void setMatcher(PatternMatcher matcher) {
public void setMatcher(ContentTypeMatcher matcher) {
this.matcher = matcher;
}
@@ -0,0 +1,16 @@
package org.apache.struts2.util;
import java.util.Map;
/**
* Matches content type of uploaded files, similar to {@link com.opensymphony.xwork2.util.PatternMatcher}
*
* @since 2.3.22
*/
public interface ContentTypeMatcher<E extends Object> {
E compilePattern(String data);
boolean match(Map<String,String> map, String data, E expr);
}
@@ -0,0 +1,20 @@
package org.apache.struts2.util;
import com.opensymphony.xwork2.util.PatternMatcher;
import com.opensymphony.xwork2.util.WildcardHelper;
import java.util.Map;
public class DefaultContentTypeMatcher implements ContentTypeMatcher<int[]> {
private PatternMatcher<int[]> matcher = new WildcardHelper();
public int[] compilePattern(String data) {
return matcher.compilePattern(data);
}
public boolean match(Map<String, String> map, String data, int[] expr) {
return matcher.match(map, data, expr);
}
}
@@ -31,8 +31,11 @@ import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.util.LocalizedTextUtil;
import com.opensymphony.xwork2.util.ValueStack;
import com.opensymphony.xwork2.util.ValueStackFactory;
import org.apache.struts2.dispatcher.DispatcherErrorHandler;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Generic test setup methods to be used with any unit testing framework.
@@ -51,7 +54,7 @@ public class StrutsTestCaseHelper {
if (params == null) {
params = new HashMap<String,String>();
}
Dispatcher du = new Dispatcher(ctx, params);
Dispatcher du = new DispatcherWrapper(ctx, params);
du.init();
Dispatcher.setInstance(du);
@@ -68,4 +71,29 @@ public class StrutsTestCaseHelper {
Dispatcher.setInstance(null);
ActionContext.setContext(null);
}
private static class DispatcherWrapper extends Dispatcher {
public DispatcherWrapper(ServletContext ctx, Map<String, String> params) {
super(ctx, params);
super.setDispatcherErrorHandler(new MockErrorHandler());
}
@Override
public void setDispatcherErrorHandler(DispatcherErrorHandler errorHandler) {
// ignore
}
}
private static class MockErrorHandler implements DispatcherErrorHandler {
public void init(ServletContext ctx) {
// ignore
}
public void handleError(HttpServletRequest request, HttpServletResponse response, int code, Exception e) {
System.out.println("Dispatcher#sendError: " + code);
e.printStackTrace(System.out);
}
}
}
@@ -27,6 +27,7 @@ import com.opensymphony.xwork2.util.logging.Logger;
import com.opensymphony.xwork2.util.logging.LoggerFactory;
import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.Map;
import java.util.Random;
@@ -51,7 +52,7 @@ public class TokenHelper {
*/
public static final String TOKEN_NAME_FIELD = "struts.token.name";
private static final Logger LOG = LoggerFactory.getLogger(TokenHelper.class);
private static final Random RANDOM = new Random();
private static final Random RANDOM = new SecureRandom();
/**
@@ -343,10 +343,7 @@ public class FreemarkerResult extends StrutsResultSupport {
contentType = "text/html";
}
String encoding = response.getCharacterEncoding();
if(encoding == null) {
encoding = template.getEncoding();
}
String encoding = template.getEncoding();
if (encoding != null) {
contentType = contentType + "; charset=" + encoding;
@@ -45,15 +45,20 @@ public class AbstractUITagBeanInfo extends SimpleBeanInfo {
List<PropertyDescriptor> descriptors = new ArrayList<PropertyDescriptor>();
// Add the tricky one first
Method setter = AbstractUITag.class.getMethod("setCssClass", String.class);
descriptors.add(new PropertyDescriptor("class", null, setter));
descriptors.add(new PropertyDescriptor("cssClass", null, setter));
Method classSetter = AbstractUITag.class.getMethod("setCssClass", String.class);
Method styleSetter = AbstractUITag.class.getMethod("setCssStyle", String.class);
descriptors.add(new PropertyDescriptor("class", null, classSetter));
descriptors.add(new PropertyDescriptor("cssClass", null, classSetter));
descriptors.add(new PropertyDescriptor("style", null, styleSetter));
descriptors.add(new PropertyDescriptor("cssStyle", null, styleSetter));
for (Field field : AbstractUITag.class.getDeclaredFields()) {
String fieldName = field.getName();
if (!"dynamicAttributes".equals(fieldName)) {
String setterName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
setter = AbstractUITag.class.getMethod(setterName, String.class);
Method setter = AbstractUITag.class.getMethod(setterName, String.class);
descriptors.add(new PropertyDescriptor(fieldName, null, setter));
}
}
@@ -63,7 +63,7 @@ function compile(ptn) {
if (ptn == '' || !window.RegExp) {
return function(val) { return val == ptn; }
} else {
var reg = new RegExp(ptn);
var reg = new RegExp("^" + ptn + "$");
return function (val) {
if (val == '') { // ignore empty option added by template
return true;
@@ -44,7 +44,7 @@ function compile(ptn) {
if (ptn == '' || !window.RegExp) {
return function(val) { return val == ptn; }
} else {
var reg = new RegExp("\\b" + ptn);
var reg = new RegExp("^" + ptn + "$");
return function (val) {
if (val == '') { // ignore empty option added by template
return true;
+3 -1
View File
@@ -52,7 +52,7 @@
ognl.TypeConverter,
com.opensymphony.xwork2.ActionContext" />
<!-- this must be valid regex, each '.' in package name must be escaped! -->
<constant name="struts.excludedPackageNamePatterns" value="^java\.lang\..*,^ognl.*,^javax.*" />
<constant name="struts.excludedPackageNamePatterns" value="^java\.lang\..*,^ognl.*,^(?!javax\.servlet\..+)(javax\..+)" />
<bean class="com.opensymphony.xwork2.ObjectFactory" name="struts"/>
<bean type="com.opensymphony.xwork2.factory.ResultFactory" name="struts" class="org.apache.struts2.factory.StrutsResultFactory" />
@@ -74,6 +74,8 @@
<bean type="com.opensymphony.xwork2.util.PatternMatcher" name="namedVariable" class="com.opensymphony.xwork2.util.NamedVariablePatternMatcher"/>
<bean type="com.opensymphony.xwork2.util.PatternMatcher" name="regex" class="org.apache.struts2.util.RegexPatternMatcher"/>
<bean type="org.apache.struts2.util.ContentTypeMatcher" name="struts" class="org.apache.struts2.util.DefaultContentTypeMatcher"/>
<bean type="org.apache.struts2.dispatcher.mapper.ActionMapper" name="struts" class="org.apache.struts2.dispatcher.mapper.DefaultActionMapper" />
<bean type="org.apache.struts2.dispatcher.mapper.ActionMapper" name="composite" class="org.apache.struts2.dispatcher.mapper.CompositeActionMapper" />
<bean type="org.apache.struts2.dispatcher.mapper.ActionMapper" name="restful" class="org.apache.struts2.dispatcher.mapper.RestfulActionMapper" />
@@ -0,0 +1,23 @@
<#--
/*
* $Id$
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* 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.
*/
-->
<#include "/${parameters.templateDir}/simple/hidden.ftl" />
@@ -0,0 +1,21 @@
<#--
/*
* 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.
*/
-->
<#lt/><div>Tag <pre style="display: inline-block">&lt;s:datetext/&gt;</pre> works only with the JavaTemplates Plugin!</div><#rt/>
@@ -0,0 +1,23 @@
<#--
/*
* 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.
*/
-->
<#include "/${parameters.templateDir}/${parameters.expandTheme}/controlheader.ftl" />
<#include "/${parameters.templateDir}/simple/datetext.ftl" />
<#include "/${parameters.templateDir}/${parameters.expandTheme}/controlfooter.ftl" />
+17 -7
View File
@@ -1,8 +1,6 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
/*
* $Id$
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -22,6 +20,11 @@
*/
-->
<project name="Struts 2">
<skin>
<groupId>org.apache.maven.skins</groupId>
<artifactId>maven-fluido-skin</artifactId>
<version>1.3.1</version>
</skin>
<bannerLeft>
<name>Apache Software Foundation</name>
<src>http://www.apache.org/images/asf-logo.gif</src>
@@ -29,19 +32,26 @@
</bannerLeft>
<bannerRight>
<name>Apache Struts</name>
<src>http://struts.apache.org/images/struts.gif</src>
<src>http://struts.apache.org/img/struts-logo.svg</src>
<href>http://struts.apache.org/</href>
</bannerRight>
<publishDate position="none"/>
<version position="none"/>
<body>
<links>
<item name="Apache"
href="http://www.apache.org/"/>
<item name="Struts"
href="http://struts.apache.org/index.html"/>
<item name="Apache" href="http://www.apache.org/"/>
<item name="Struts" href="http://struts.apache.org/"/>
</links>
<menu ref="parent"/>
<menu ref="reports"/>
<footer>
<div class="row span12">
Apache Struts, Struts, Apache, the Apache feather logo, and the Apache Struts
project logos are trademarks of The Apache Software Foundation.
</div>
</footer>
</body>
</project>
@@ -58,7 +58,8 @@ public class ServletActionRedirectResultTest extends StrutsInternalTestCase {
.addParam("location", "someLocation")
.addParam("prependServletContext", "true")
.addParam("method", "someMethod")
.addParam("param1", "${#value1}")
.addParam("statusCode", "333")
.addParam("param1", "${#value1}")
.addParam("param2", "${#value2}")
.addParam("param3", "${#value3}")
.addParam("anchor", "${#fragment}")
@@ -100,6 +100,36 @@ public class ServletRedirectResultTest extends StrutsInternalTestCase implements
}
}
public void testFullUrlRedirectWithSpaces() {
view.setLocation("http://localhost/bar/foo some.pdf");
responseMock.expectAndReturn("encodeRedirectURL", C.args(C.eq("http://localhost/bar/foo some.pdf")), "http://localhost/bar/foo some.pdf");
responseMock.expect("sendRedirect", C.args(C.eq("http://localhost/bar/foo some.pdf")));
try {
view.execute(ai);
requestMock.verify();
responseMock.verify();
} catch (Exception e) {
e.printStackTrace();
fail();
}
}
public void testFullUrlRedirectWithParams() {
view.setLocation("http://localhost/bar/foo.action?param=1&param 2=3");
responseMock.expectAndReturn("encodeRedirectURL", C.args(C.eq("http://localhost/bar/foo.action?param=1&param 2=3")), "http://localhost/bar/foo.action?param=1&param 2=3");
responseMock.expect("sendRedirect", C.args(C.eq("http://localhost/bar/foo.action?param=1&param 2=3")));
try {
view.execute(ai);
requestMock.verify();
responseMock.verify();
} catch (Exception e) {
e.printStackTrace();
fail();
}
}
public void testAbsoluteRedirect303() {
view.setLocation("/bar/foo.jsp");
view.setStatusCode(303);
@@ -27,6 +27,7 @@ import java.util.Map;
import javax.servlet.http.Cookie;
import com.opensymphony.xwork2.security.DefaultAcceptedPatternsChecker;
import com.opensymphony.xwork2.security.DefaultExcludedPatternsChecker;
import com.opensymphony.xwork2.mock.MockActionInvocation;
import org.easymock.MockControl;
@@ -44,11 +45,11 @@ public class CookieInterceptorTest extends StrutsInternalTestCase {
public void testIntercepDefault() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setCookies(new Cookie[] {
request.setCookies(
new Cookie("cookie1", "cookie1value"),
new Cookie("cookie2", "cookie2value"),
new Cookie("cookie3", "cookie3value")
});
);
ServletActionContext.setRequest(request);
MockActionWithCookieAware action = new MockActionWithCookieAware();
@@ -67,6 +68,7 @@ public class CookieInterceptorTest extends StrutsInternalTestCase {
// by default the interceptor doesn't accept any cookies
CookieInterceptor interceptor = new CookieInterceptor();
interceptor.setExcludedPatternsChecker(new DefaultExcludedPatternsChecker());
interceptor.setAcceptedPatternsChecker(new DefaultAcceptedPatternsChecker());
interceptor.intercept(invocation);
@@ -81,11 +83,11 @@ public class CookieInterceptorTest extends StrutsInternalTestCase {
public void testInterceptAll1() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setCookies(new Cookie[] {
request.setCookies(
new Cookie("cookie1", "cookie1value"),
new Cookie("cookie2", "cookie2value"),
new Cookie("cookie3", "cookie3value")
});
);
ServletActionContext.setRequest(request);
MockActionWithCookieAware action = new MockActionWithCookieAware();
@@ -103,6 +105,7 @@ public class CookieInterceptorTest extends StrutsInternalTestCase {
CookieInterceptor interceptor = new CookieInterceptor();
interceptor.setExcludedPatternsChecker(new DefaultExcludedPatternsChecker());
interceptor.setAcceptedPatternsChecker(new DefaultAcceptedPatternsChecker());
interceptor.setCookiesName("*");
interceptor.setCookiesValue("*");
interceptor.intercept(invocation);
@@ -123,11 +126,11 @@ public class CookieInterceptorTest extends StrutsInternalTestCase {
public void testInterceptAll2() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setCookies(new Cookie[] {
request.setCookies(
new Cookie("cookie1", "cookie1value"),
new Cookie("cookie2", "cookie2value"),
new Cookie("cookie3", "cookie3value")
});
);
ServletActionContext.setRequest(request);
MockActionWithCookieAware action = new MockActionWithCookieAware();
@@ -145,6 +148,7 @@ public class CookieInterceptorTest extends StrutsInternalTestCase {
CookieInterceptor interceptor = new CookieInterceptor();
interceptor.setExcludedPatternsChecker(new DefaultExcludedPatternsChecker());
interceptor.setAcceptedPatternsChecker(new DefaultAcceptedPatternsChecker());
interceptor.setCookiesName("cookie1, cookie2, cookie3");
interceptor.setCookiesValue("cookie1value, cookie2value, cookie3value");
interceptor.intercept(invocation);
@@ -164,11 +168,11 @@ public class CookieInterceptorTest extends StrutsInternalTestCase {
public void testInterceptSelectedCookiesNameOnly1() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setCookies(new Cookie[] {
request.setCookies(
new Cookie("cookie1", "cookie1value"),
new Cookie("cookie2", "cookie2value"),
new Cookie("cookie3", "cookie3value")
});
);
ServletActionContext.setRequest(request);
MockActionWithCookieAware action = new MockActionWithCookieAware();
@@ -186,6 +190,7 @@ public class CookieInterceptorTest extends StrutsInternalTestCase {
CookieInterceptor interceptor = new CookieInterceptor();
interceptor.setExcludedPatternsChecker(new DefaultExcludedPatternsChecker());
interceptor.setAcceptedPatternsChecker(new DefaultAcceptedPatternsChecker());
interceptor.setCookiesName("cookie1, cookie3");
interceptor.setCookiesValue("cookie1value, cookie2value, cookie3value");
interceptor.intercept(invocation);
@@ -205,11 +210,11 @@ public class CookieInterceptorTest extends StrutsInternalTestCase {
public void testInterceptSelectedCookiesNameOnly2() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setCookies(new Cookie[] {
request.setCookies(
new Cookie("cookie1", "cookie1value"),
new Cookie("cookie2", "cookie2value"),
new Cookie("cookie3", "cookie3value")
});
);
ServletActionContext.setRequest(request);
MockActionWithCookieAware action = new MockActionWithCookieAware();
@@ -227,6 +232,7 @@ public class CookieInterceptorTest extends StrutsInternalTestCase {
CookieInterceptor interceptor = new CookieInterceptor();
interceptor.setExcludedPatternsChecker(new DefaultExcludedPatternsChecker());
interceptor.setAcceptedPatternsChecker(new DefaultAcceptedPatternsChecker());
interceptor.setCookiesName("cookie1, cookie3");
interceptor.setCookiesValue("*");
interceptor.intercept(invocation);
@@ -246,11 +252,11 @@ public class CookieInterceptorTest extends StrutsInternalTestCase {
public void testInterceptSelectedCookiesNameOnly3() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setCookies(new Cookie[] {
request.setCookies(
new Cookie("cookie1", "cookie1value"),
new Cookie("cookie2", "cookie2value"),
new Cookie("cookie3", "cookie3value")
});
);
ServletActionContext.setRequest(request);
MockActionWithCookieAware action = new MockActionWithCookieAware();
@@ -268,6 +274,7 @@ public class CookieInterceptorTest extends StrutsInternalTestCase {
CookieInterceptor interceptor = new CookieInterceptor();
interceptor.setExcludedPatternsChecker(new DefaultExcludedPatternsChecker());
interceptor.setAcceptedPatternsChecker(new DefaultAcceptedPatternsChecker());
interceptor.setCookiesName("cookie1, cookie3");
interceptor.setCookiesValue("");
interceptor.intercept(invocation);
@@ -288,11 +295,11 @@ public class CookieInterceptorTest extends StrutsInternalTestCase {
public void testInterceptSelectedCookiesNameAndValue() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setCookies(new Cookie[] {
request.setCookies(
new Cookie("cookie1", "cookie1value"),
new Cookie("cookie2", "cookie2value"),
new Cookie("cookie3", "cookie3value")
});
);
ServletActionContext.setRequest(request);
MockActionWithCookieAware action = new MockActionWithCookieAware();
@@ -310,6 +317,7 @@ public class CookieInterceptorTest extends StrutsInternalTestCase {
CookieInterceptor interceptor = new CookieInterceptor();
interceptor.setExcludedPatternsChecker(new DefaultExcludedPatternsChecker());
interceptor.setAcceptedPatternsChecker(new DefaultAcceptedPatternsChecker());
interceptor.setCookiesName("cookie1, cookie3");
interceptor.setCookiesValue("cookie1value");
interceptor.intercept(invocation);
@@ -371,6 +379,7 @@ public class CookieInterceptorTest extends StrutsInternalTestCase {
}
};
interceptor.setExcludedPatternsChecker(new DefaultExcludedPatternsChecker());
interceptor.setAcceptedPatternsChecker(new DefaultAcceptedPatternsChecker());
interceptor.setCookiesName("*");
MockActionInvocation invocation = new MockActionInvocation();
@@ -431,6 +440,7 @@ public class CookieInterceptorTest extends StrutsInternalTestCase {
}
};
interceptor.setExcludedPatternsChecker(new DefaultExcludedPatternsChecker());
interceptor.setAcceptedPatternsChecker(new DefaultAcceptedPatternsChecker());
interceptor.setCookiesName("*");
MockActionInvocation invocation = new MockActionInvocation();
@@ -0,0 +1,81 @@
/*
* $Id$
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.struts2.util;
import com.opensymphony.xwork2.ognl.SecurityMemberAccess;
import org.apache.struts2.StrutsInternalTestCase;
import org.apache.struts2.TestAction;
import javax.servlet.jsp.tagext.TagSupport;
import java.lang.reflect.Member;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
public class SecurityMemberAccessInServletsTest extends StrutsInternalTestCase {
private Map context;
@Override
public void setUp() throws Exception {
context = new HashMap();
}
public void testJavaxServletPackageAccess() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(false);
Set<Pattern> excluded = new HashSet<Pattern>();
excluded.add(Pattern.compile("^(?!javax\\.servlet\\..+)(javax\\..+)"));
sma.setExcludedPackageNamePatterns(excluded);
String propertyName = "value";
Member member = TagSupport.class.getMethod("doStartTag");
// when
boolean actual = sma.isAccessible(context, new TestAction(), member, propertyName);
// then
assertTrue("javax.servlet package isn't accessible!", actual);
}
public void testJavaxServletPackageExclusion() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(false);
Set<Pattern> excluded = new HashSet<Pattern>();
excluded.add(Pattern.compile("^javax\\..+"));
sma.setExcludedPackageNamePatterns(excluded);
String propertyName = "value";
Member member = TagSupport.class.getMethod("doStartTag");
// when
boolean actual = sma.isAccessible(context, new TestAction(), member, propertyName);
// then
assertFalse("javax.servlet package is accessible!", actual);
}
}
@@ -6,6 +6,7 @@ import com.opensymphony.xwork2.util.ClassLoaderUtil;
import com.opensymphony.xwork2.util.ValueStack;
import com.opensymphony.xwork2.util.fs.DefaultFileManagerFactory;
import freemarker.template.Configuration;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.StrutsInternalTestCase;
@@ -34,26 +35,17 @@ public class FreemarkerResultMockedTest extends StrutsInternalTestCase {
PrintWriter writer;
StringWriter stringWriter;
ServletContext servletContext;
FreemarkerManager mgr;
MockHttpServletRequest request;
public void testActionThatThrowsExceptionTag() throws Exception {
//get fm config to use it in mock servlet context
FreemarkerManager freemarkerManager = container.getInstance(FreemarkerManager.class);
Configuration freemarkerConfig = freemarkerManager.getConfiguration(ServletActionContext.getServletContext());
freemarkerConfig.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
Configuration freemarkerConfig;
servletContext = EasyMock.createNiceMock(ServletContext.class);
public void testActionThatThrowsExceptionTag() throws Exception {
File file = new File(FreeMarkerResultTest.class.getResource("callActionFreeMarker2.ftl").toURI());
EasyMock.expect(servletContext.getRealPath("/tutorial/org/apache/struts2/views/freemarker/callActionFreeMarker.ftl")).andReturn(file.getAbsolutePath());
file = new File(FreeMarkerResultTest.class.getResource("nested.ftl").toURI());
EasyMock.expect(servletContext.getRealPath("/tutorial/org/apache/struts2/views/freemarker/nested.ftl")).andReturn(file.getAbsolutePath());
EasyMock.expect(servletContext.getAttribute(FreemarkerManager.CONFIG_SERVLET_CONTEXT_KEY)).andReturn(freemarkerConfig).anyTimes();
EasyMock.replay(servletContext);
freemarkerConfig.setServletContextForTemplateLoading(servletContext, null);
ServletActionContext.setServletContext(servletContext);
init();
request.setRequestURI("/tutorial/test2.action");
@@ -63,22 +55,12 @@ public class FreemarkerResultMockedTest extends StrutsInternalTestCase {
}
public void testActionThatSucceedsTag() throws Exception {
//get fm config to use it in mock servlet context
FreemarkerManager freemarkerManager = container.getInstance(FreemarkerManager.class);
Configuration freemarkerConfig = freemarkerManager.getConfiguration(ServletActionContext.getServletContext());
freemarkerConfig.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
servletContext = EasyMock.createNiceMock(ServletContext.class);
File file = new File(FreeMarkerResultTest.class.getResource("callActionFreeMarker2.ftl").toURI());
EasyMock.expect(servletContext.getRealPath("/tutorial/org/apache/struts2/views/freemarker/callActionFreeMarker2.ftl")).andReturn(file.getAbsolutePath());
file = new File(FreeMarkerResultTest.class.getResource("nested.ftl").toURI());
EasyMock.expect(servletContext.getRealPath("/tutorial/org/apache/struts2/views/freemarker/nested.ftl")).andReturn(file.getAbsolutePath());
EasyMock.expect(servletContext.getAttribute(FreemarkerManager.CONFIG_SERVLET_CONTEXT_KEY)).andReturn(freemarkerConfig).anyTimes();
EasyMock.replay(servletContext);
freemarkerConfig.setServletContextForTemplateLoading(servletContext, null);
ServletActionContext.setServletContext(servletContext);
init();
request.setRequestURI("/tutorial/test5.action");
@@ -88,13 +70,6 @@ public class FreemarkerResultMockedTest extends StrutsInternalTestCase {
}
public void testDynamicAttributesSupport() throws Exception {
//get fm config to use it in mock servlet context
FreemarkerManager freemarkerManager = container.getInstance(FreemarkerManager.class);
Configuration freemarkerConfig = freemarkerManager.getConfiguration(ServletActionContext.getServletContext());
freemarkerConfig.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
servletContext = EasyMock.createNiceMock(ServletContext.class);
File file = new File(FreeMarkerResultTest.class.getResource("dynaAttributes.ftl").toURI());
EasyMock.expect(servletContext.getRealPath("/tutorial/org/apache/struts2/views/freemarker/dynaAttributes.ftl")).andReturn(file.getAbsolutePath());
@@ -117,12 +92,8 @@ public class FreemarkerResultMockedTest extends StrutsInternalTestCase {
EasyMock.expect(servletContext.getRealPath("/template/simple/dynamic-attributes.ftl")).andReturn(file.getAbsolutePath());
EasyMock.expect(servletContext.getRealPath("/template/~~~simple/dynamic-attributes.ftl")).andReturn(file.getAbsolutePath());
EasyMock.expect(servletContext.getAttribute(FreemarkerManager.CONFIG_SERVLET_CONTEXT_KEY)).andReturn(freemarkerConfig).anyTimes();
EasyMock.replay(servletContext);
freemarkerConfig.setServletContextForTemplateLoading(servletContext, null);
ServletActionContext.setServletContext(servletContext);
init();
request.setRequestURI("/tutorial/test6.action");
@@ -150,12 +121,6 @@ public class FreemarkerResultMockedTest extends StrutsInternalTestCase {
}
public void testManualListInTemplate() throws Exception {
FreemarkerManager freemarkerManager = container.getInstance(FreemarkerManager.class);
Configuration freemarkerConfig = freemarkerManager.getConfiguration(ServletActionContext.getServletContext());
freemarkerConfig.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
servletContext = EasyMock.createNiceMock(ServletContext.class);
File file = new File(FreeMarkerResultTest.class.getResource("manual-list.ftl").toURI());
EasyMock.expect(servletContext.getRealPath("/tutorial/org/apache/struts2/views/freemarker/manual-list.ftl")).andReturn(file.getAbsolutePath());
@@ -178,12 +143,8 @@ public class FreemarkerResultMockedTest extends StrutsInternalTestCase {
EasyMock.expect(servletContext.getRealPath("/template/simple/dynamic-attributes.ftl")).andReturn(file.getAbsolutePath());
EasyMock.expect(servletContext.getRealPath("/template/~~~simple/dynamic-attributes.ftl")).andReturn(file.getAbsolutePath());
EasyMock.expect(servletContext.getAttribute(FreemarkerManager.CONFIG_SERVLET_CONTEXT_KEY)).andReturn(freemarkerConfig).anyTimes();
EasyMock.replay(servletContext);
freemarkerConfig.setServletContextForTemplateLoading(servletContext, null);
ServletActionContext.setServletContext(servletContext);
init();
request.setRequestURI("/tutorial/test7.action");
@@ -198,24 +159,14 @@ public class FreemarkerResultMockedTest extends StrutsInternalTestCase {
}
public void testDynamicAttributesInTheme() throws Exception {
FreemarkerManager freemarkerManager = container.getInstance(FreemarkerManager.class);
Configuration freemarkerConfig = freemarkerManager.getConfiguration(ServletActionContext.getServletContext());
freemarkerConfig.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
servletContext = EasyMock.createNiceMock(ServletContext.class);
File file = new File(FreeMarkerResultTest.class.getResource("customTextField.ftl").toURI());
EasyMock.expect(servletContext.getRealPath("/tutorial/org/apache/struts2/views/freemarker/customTextField.ftl")).andReturn(file.getAbsolutePath());
file = new File(ClassLoaderUtil.getResource("template/test/text.ftl", getClass()).toURI());
EasyMock.expect(servletContext.getRealPath("/template/test/text.ftl")).andReturn(file.getAbsolutePath());
EasyMock.expect(servletContext.getAttribute(FreemarkerManager.CONFIG_SERVLET_CONTEXT_KEY)).andReturn(freemarkerConfig).anyTimes();
EasyMock.replay(servletContext);
freemarkerConfig.setServletContextForTemplateLoading(servletContext, null);
ServletActionContext.setServletContext(servletContext);
init();
request.setRequestURI("/tutorial/test8.action");
@@ -226,17 +177,6 @@ public class FreemarkerResultMockedTest extends StrutsInternalTestCase {
}
private void init() throws MalformedURLException, URISyntaxException {
mgr = new FreemarkerManager();
mgr.setEncoding("UTF-8");
DefaultFileManagerFactory factory = new DefaultFileManagerFactory();
container.inject(factory);
mgr.setFileManagerFactory(factory);
FreemarkerThemeTemplateLoader themeLoader = new FreemarkerThemeTemplateLoader();
container.inject(themeLoader);
mgr.setThemeTemplateLoader(themeLoader);
stringWriter = new StringWriter();
writer = new PrintWriter(stringWriter);
response = new StrutsMockHttpServletResponse();
@@ -257,6 +197,24 @@ public class FreemarkerResultMockedTest extends StrutsInternalTestCase {
invocation = new MockActionInvocation();
invocation.setStack(stack);
invocation.setInvocationContext(context);
//get fm config to use it in mock servlet context
FreemarkerManager freemarkerManager = container.getInstance(FreemarkerManager.class);
freemarkerConfig = freemarkerManager.getConfiguration(ServletActionContext.getServletContext());
freemarkerConfig.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
freemarkerConfig.setServletContextForTemplateLoading(servletContext, null);
}
@Override
public void setUp() throws Exception {
super.setUp();
servletContext = EasyMock.createNiceMock(ServletContext.class);
EasyMock.expect(servletContext.getInitParameter("TemplatePath")).andReturn(null);
EasyMock.expect(servletContext.getInitParameter("templatePath")).andReturn(null);
EasyMock.expect(servletContext.getAttribute(FreemarkerManager.CONFIG_SERVLET_CONTEXT_KEY)).andReturn(freemarkerConfig).anyTimes();
}
}
@@ -115,7 +115,9 @@ public class TextTagTest extends AbstractTagTest {
params.add(param2);
params.add(param3);
String expected = MessageFormat.format(pattern, params.toArray());
MessageFormat format = new MessageFormat(pattern, ActionContext.getContext().getLocale());
String expected = format.format(params.toArray());
tag.setName(key);
tag.doStartTag();
((Text) tag.component).addParameter(param1);
+1 -1
View File
@@ -25,7 +25,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>2.3.19</version>
<version>2.3.22</version>
</parent>
<artifactId>struts2-cdi-plugin</artifactId>
@@ -70,7 +70,6 @@ public class CdiObjectFactory extends ObjectFactory {
}
protected BeanManager beanManager;
protected CreationalContext ctx;
Map<Class<?>, InjectionTarget<?>> injectionTargetCache = new ConcurrentHashMap<Class<?>, InjectionTarget<?>>();
@@ -79,7 +78,6 @@ public class CdiObjectFactory extends ObjectFactory {
LOG.info("Initializing Struts2 CDI integration...");
this.beanManager = findBeanManager();
if (beanManager != null) {
this.ctx = buildNonContextualCreationalContext(beanManager);
LOG.info("Struts2 CDI integration initialized.");
} else {
LOG.error("Struts2 CDI integration could not be initialized.");
@@ -152,13 +150,16 @@ public class CdiObjectFactory extends ObjectFactory {
}
@Override
@SuppressWarnings("unchecked")
@SuppressWarnings({ "rawtypes", "unchecked" })
public Object buildBean(String className, Map<String, Object> extraContext, boolean injectInternal)
throws Exception {
Class<?> clazz = getClassInstance(className);
InjectionTarget injectionTarget = getInjectionTarget(clazz);
// a separate CreationalContext is required for every bean
final CreationalContext ctx = buildNonContextualCreationalContext(beanManager);
Object o = injectionTarget.produce(ctx);
injectionTarget.inject(o, ctx);
injectionTarget.postConstruct(o);
+57
View File
@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
-->
<project name="Struts 2">
<skin>
<groupId>org.apache.maven.skins</groupId>
<artifactId>maven-fluido-skin</artifactId>
<version>1.3.1</version>
</skin>
<bannerLeft>
<name>Apache Software Foundation</name>
<src>http://www.apache.org/images/asf-logo.gif</src>
<href>http://www.apache.org/</href>
</bannerLeft>
<bannerRight>
<name>Apache Struts</name>
<src>http://struts.apache.org/img/struts-logo.svg</src>
<href>http://struts.apache.org/</href>
</bannerRight>
<publishDate position="none"/>
<version position="none"/>
<body>
<links>
<item name="Apache" href="http://www.apache.org/"/>
<item name="Struts" href="http://struts.apache.org/"/>
</links>
<menu ref="parent"/>
<menu ref="reports"/>
<footer>
<div class="row span12">
Apache Struts, Struts, Apache, the Apache feather logo, and the Apache Struts
project logos are trademarks of The Apache Software Foundation.
</div>
</footer>
</body>
</project>
+1 -1
View File
@@ -26,7 +26,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>2.3.19</version>
<version>2.3.22</version>
</parent>
<artifactId>struts2-codebehind-plugin</artifactId>
+57
View File
@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
-->
<project name="Struts 2">
<skin>
<groupId>org.apache.maven.skins</groupId>
<artifactId>maven-fluido-skin</artifactId>
<version>1.3.1</version>
</skin>
<bannerLeft>
<name>Apache Software Foundation</name>
<src>http://www.apache.org/images/asf-logo.gif</src>
<href>http://www.apache.org/</href>
</bannerLeft>
<bannerRight>
<name>Apache Struts</name>
<src>http://struts.apache.org/img/struts-logo.svg</src>
<href>http://struts.apache.org/</href>
</bannerRight>
<publishDate position="none"/>
<version position="none"/>
<body>
<links>
<item name="Apache" href="http://www.apache.org/"/>
<item name="Struts" href="http://struts.apache.org/"/>
</links>
<menu ref="parent"/>
<menu ref="reports"/>
<footer>
<div class="row span12">
Apache Struts, Struts, Apache, the Apache feather logo, and the Apache Struts
project logos are trademarks of The Apache Software Foundation.
</div>
</footer>
</body>
</project>
+1 -1
View File
@@ -26,7 +26,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>2.3.19</version>
<version>2.3.22</version>
</parent>
<artifactId>struts2-config-browser-plugin</artifactId>
+57
View File
@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
-->
<project name="Struts 2">
<skin>
<groupId>org.apache.maven.skins</groupId>
<artifactId>maven-fluido-skin</artifactId>
<version>1.3.1</version>
</skin>
<bannerLeft>
<name>Apache Software Foundation</name>
<src>http://www.apache.org/images/asf-logo.gif</src>
<href>http://www.apache.org/</href>
</bannerLeft>
<bannerRight>
<name>Apache Struts</name>
<src>http://struts.apache.org/img/struts-logo.svg</src>
<href>http://struts.apache.org/</href>
</bannerRight>
<publishDate position="none"/>
<version position="none"/>
<body>
<links>
<item name="Apache" href="http://www.apache.org/"/>
<item name="Struts" href="http://struts.apache.org/"/>
</links>
<menu ref="parent"/>
<menu ref="reports"/>
<footer>
<div class="row span12">
Apache Struts, Struts, Apache, the Apache feather logo, and the Apache Struts
project logos are trademarks of The Apache Software Foundation.
</div>
</footer>
</body>
</project>
+1 -1
View File
@@ -3,7 +3,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>2.3.19</version>
<version>2.3.22</version>
</parent>
<artifactId>struts2-convention-plugin</artifactId>
@@ -38,7 +38,8 @@ import com.opensymphony.xwork2.util.TextParseUtil;
import com.opensymphony.xwork2.util.WildcardHelper;
import com.opensymphony.xwork2.util.classloader.ReloadingClassLoader;
import com.opensymphony.xwork2.util.finder.ClassFinder;
import com.opensymphony.xwork2.util.finder.ClassFinder.ClassInfo;
import com.opensymphony.xwork2.util.finder.ClassFinderFactory;
import com.opensymphony.xwork2.util.finder.DefaultClassFinder;
import com.opensymphony.xwork2.util.finder.ClassLoaderInterface;
import com.opensymphony.xwork2.util.finder.ClassLoaderInterfaceDelegate;
import com.opensymphony.xwork2.util.finder.Test;
@@ -93,7 +94,7 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder {
private String[] actionPackages;
private String[] excludePackages;
private String[] packageLocators;
private String[] includeJars = new String[] { ".*?\\.jar(!/|/)?" };
private String[] includeJars;
private String packageLocatorsBasePackage;
private boolean disableActionScanning = false;
private boolean disablePackageLocatorsScanning = false;
@@ -113,6 +114,7 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder {
private boolean eagerLoading = false;
private FileManager fileManager;
private ClassFinderFactory classFinderFactory;
/**
* Constructs actions based on a list of packages.
@@ -303,6 +305,11 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder {
this.fileManager = fileManagerFactory.getFileManager();
}
@Inject(required = false)
public void setClassFinderFactory(ClassFinderFactory classFinderFactory) {
this.classFinderFactory = classFinderFactory;
}
protected void initReloadClassLoader() {
//when the configuration is reloaded, a new classloader will be setup
if (isReloadEnabled() && reloadingClassLoader == null)
@@ -387,7 +394,7 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder {
// specified by the user
Test<String> classPackageTest = getClassPackageTest();
List<URL> urls = readUrls();
ClassFinder finder = new ClassFinder(getClassLoaderInterface(), urls, EXTRACT_BASE_INTERFACES, fileProtocols, classPackageTest);
ClassFinder finder = buildClassFinder(classPackageTest, urls);
Test<ClassFinder.ClassInfo> test = getActionClassTest();
classes.addAll(finder.findClasses(test));
@@ -400,6 +407,16 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder {
return classes;
}
protected ClassFinder buildClassFinder(Test<String> classPackageTest, List<URL> urls) {
if (classFinderFactory != null) {
LOG.trace("Using ClassFinderFactory to create instance of ClassFinder!");
return classFinderFactory.buildClassFinder(getClassLoaderInterface(), urls, EXTRACT_BASE_INTERFACES, fileProtocols, classPackageTest);
} else {
LOG.trace("ClassFinderFactory not defined, fallback to default ClassFinder implementation");
return new DefaultClassFinder(getClassLoaderInterface(), urls, EXTRACT_BASE_INTERFACES, fileProtocols, classPackageTest);
}
}
private List<URL> readUrls() throws IOException {
List<URL> resourceUrls = new ArrayList<URL>();
// Usually the "classes" dir.
@@ -458,35 +475,43 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder {
urlSet = urlSet.excludePaths(System.getProperty("sun.boot.class.path", ""));
urlSet = urlSet.exclude(".*/JavaVM.framework/.*");
List<URL> rawIncludedUrls = urlSet.getUrls();
Set<URL> includeUrls = new HashSet<URL>();
boolean[] patternUsed = new boolean[includeJars.length];
if (includeJars == null) {
urlSet = urlSet.exclude(".*?\\.jar(!/|/)?");
} else {
LOG.debug("jar urls regexes were specified: #0", Arrays.asList(includeJars));
for (URL url : rawIncludedUrls) {
if (fileProtocols.contains(url.getProtocol())) {
//it is a jar file, make sure it macthes at least a url regex
for (int i = 0; i < includeJars.length; i++) {
String includeJar = includeJars[i];
if (Pattern.matches(includeJar, url.toExternalForm())) {
includeUrls.add(url);
patternUsed[i] = true;
break;
List<URL> rawIncludedUrls = urlSet.getUrls();
Set<URL> includeUrls = new HashSet<URL>();
boolean[] patternUsed = new boolean[includeJars.length];
for (URL url : rawIncludedUrls) {
if (fileProtocols.contains(url.getProtocol())) {
//it is a jar file, make sure it macthes at least a url regex
for (int i = 0; i < includeJars.length; i++) {
String includeJar = includeJars[i];
if (Pattern.matches(includeJar, url.toExternalForm())) {
includeUrls.add(url);
patternUsed[i] = true;
break;
}
}
} else {
LOG.debug("It is not a jar [#0]", url);
includeUrls.add(url);
}
}
if (LOG.isWarnEnabled()) {
for (int i = 0; i < patternUsed.length; i++) {
if (!patternUsed[i]) {
LOG.warn("The includeJars pattern [#0] did not match any jars in the classpath", includeJars[i]);
}
}
} else {
//it is not a jar
includeUrls.add(url);
}
return new UrlSet(includeUrls);
}
if (LOG.isWarnEnabled()) {
for (int i = 0; i < patternUsed.length; i++) {
if (!patternUsed[i]) {
LOG.warn("The includeJars pattern [#0] did not match any jars in the classpath", includeJars[i]);
}
}
}
return new UrlSet(includeUrls);
return urlSet;
}
/**
@@ -496,7 +521,7 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder {
* goal is to avoid loading the class if we don't have to, the (actionSuffix
* || implements Action) test will have to remain until later. See
* {@link #getActionClassTest()} for the test performed on the loaded
* {@link ClassInfo} structure.
* {@link ClassFinder.ClassInfo} structure.
*
* @param className the name of the class to test
* @return true if the specified class should be included in the
@@ -588,7 +613,7 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder {
/**
* Construct a {@link Test} Object that determines if a specified class
* should be included in the package scan based on the full {@link ClassInfo}
* should be included in the package scan based on the full {@link ClassFinder.ClassInfo}
* of the class. At this point, the class has been loaded, so it's ok to
* perform tests such as checking annotations or looking at interfaces or
* super-classes of the specified class.
@@ -1121,4 +1146,5 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder {
} else
return false;
}
}
+57
View File
@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
-->
<project name="Struts 2">
<skin>
<groupId>org.apache.maven.skins</groupId>
<artifactId>maven-fluido-skin</artifactId>
<version>1.3.1</version>
</skin>
<bannerLeft>
<name>Apache Software Foundation</name>
<src>http://www.apache.org/images/asf-logo.gif</src>
<href>http://www.apache.org/</href>
</bannerLeft>
<bannerRight>
<name>Apache Struts</name>
<src>http://struts.apache.org/img/struts-logo.svg</src>
<href>http://struts.apache.org/</href>
</bannerRight>
<publishDate position="none"/>
<version position="none"/>
<body>
<links>
<item name="Apache" href="http://www.apache.org/"/>
<item name="Struts" href="http://struts.apache.org/"/>
</links>
<menu ref="parent"/>
<menu ref="reports"/>
<footer>
<div class="row span12">
Apache Struts, Struts, Apache, the Apache feather logo, and the Apache Struts
project logos are trademarks of The Apache Software Foundation.
</div>
</footer>
</body>
</project>
+1 -1
View File
@@ -25,7 +25,7 @@
<parent>
<artifactId>struts2-plugins</artifactId>
<groupId>org.apache.struts</groupId>
<version>2.3.19</version>
<version>2.3.22</version>
</parent>
<modelVersion>4.0.0</modelVersion>
+57
View File
@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
-->
<project name="Struts 2">
<skin>
<groupId>org.apache.maven.skins</groupId>
<artifactId>maven-fluido-skin</artifactId>
<version>1.3.1</version>
</skin>
<bannerLeft>
<name>Apache Software Foundation</name>
<src>http://www.apache.org/images/asf-logo.gif</src>
<href>http://www.apache.org/</href>
</bannerLeft>
<bannerRight>
<name>Apache Struts</name>
<src>http://struts.apache.org/img/struts-logo.svg</src>
<href>http://struts.apache.org/</href>
</bannerRight>
<publishDate position="none"/>
<version position="none"/>
<body>
<links>
<item name="Apache" href="http://www.apache.org/"/>
<item name="Struts" href="http://struts.apache.org/"/>
</links>
<menu ref="parent"/>
<menu ref="reports"/>
<footer>
<div class="row span12">
Apache Struts, Struts, Apache, the Apache feather logo, and the Apache Struts
project logos are trademarks of The Apache Software Foundation.
</div>
</footer>
</body>
</project>
+1 -1
View File
@@ -26,7 +26,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>2.3.19</version>
<version>2.3.22</version>
</parent>
<artifactId>struts2-dwr-plugin</artifactId>
+57
View File
@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
-->
<project name="Struts 2">
<skin>
<groupId>org.apache.maven.skins</groupId>
<artifactId>maven-fluido-skin</artifactId>
<version>1.3.1</version>
</skin>
<bannerLeft>
<name>Apache Software Foundation</name>
<src>http://www.apache.org/images/asf-logo.gif</src>
<href>http://www.apache.org/</href>
</bannerLeft>
<bannerRight>
<name>Apache Struts</name>
<src>http://struts.apache.org/img/struts-logo.svg</src>
<href>http://struts.apache.org/</href>
</bannerRight>
<publishDate position="none"/>
<version position="none"/>
<body>
<links>
<item name="Apache" href="http://www.apache.org/"/>
<item name="Struts" href="http://struts.apache.org/"/>
</links>
<menu ref="parent"/>
<menu ref="reports"/>
<footer>
<div class="row span12">
Apache Struts, Struts, Apache, the Apache feather logo, and the Apache Struts
project logos are trademarks of The Apache Software Foundation.
</div>
</footer>
</body>
</project>
+1 -1
View File
@@ -26,7 +26,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>2.3.19</version>
<version>2.3.22</version>
</parent>
<artifactId>struts2-embeddedjsp-plugin</artifactId>
+57
View File
@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
-->
<project name="Struts 2">
<skin>
<groupId>org.apache.maven.skins</groupId>
<artifactId>maven-fluido-skin</artifactId>
<version>1.3.1</version>
</skin>
<bannerLeft>
<name>Apache Software Foundation</name>
<src>http://www.apache.org/images/asf-logo.gif</src>
<href>http://www.apache.org/</href>
</bannerLeft>
<bannerRight>
<name>Apache Struts</name>
<src>http://struts.apache.org/img/struts-logo.svg</src>
<href>http://struts.apache.org/</href>
</bannerRight>
<publishDate position="none"/>
<version position="none"/>
<body>
<links>
<item name="Apache" href="http://www.apache.org/"/>
<item name="Struts" href="http://struts.apache.org/"/>
</links>
<menu ref="parent"/>
<menu ref="reports"/>
<footer>
<div class="row span12">
Apache Struts, Struts, Apache, the Apache feather logo, and the Apache Struts
project logos are trademarks of The Apache Software Foundation.
</div>
</footer>
</body>
</project>
+1 -1
View File
@@ -3,7 +3,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>2.3.19</version>
<version>2.3.22</version>
</parent>
<artifactId>struts2-gxp-plugin</artifactId>
+57
View File
@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
-->
<project name="Struts 2">
<skin>
<groupId>org.apache.maven.skins</groupId>
<artifactId>maven-fluido-skin</artifactId>
<version>1.3.1</version>
</skin>
<bannerLeft>
<name>Apache Software Foundation</name>
<src>http://www.apache.org/images/asf-logo.gif</src>
<href>http://www.apache.org/</href>
</bannerLeft>
<bannerRight>
<name>Apache Struts</name>
<src>http://struts.apache.org/img/struts-logo.svg</src>
<href>http://struts.apache.org/</href>
</bannerRight>
<publishDate position="none"/>
<version position="none"/>
<body>
<links>
<item name="Apache" href="http://www.apache.org/"/>
<item name="Struts" href="http://struts.apache.org/"/>
</links>
<menu ref="parent"/>
<menu ref="reports"/>
<footer>
<div class="row span12">
Apache Struts, Struts, Apache, the Apache feather logo, and the Apache Struts
project logos are trademarks of The Apache Software Foundation.
</div>
</footer>
</body>
</project>
+1 -1
View File
@@ -26,7 +26,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>2.3.19</version>
<version>2.3.22</version>
</parent>
<artifactId>struts2-jasperreports-plugin</artifactId>
+57
View File
@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
-->
<project name="Struts 2">
<skin>
<groupId>org.apache.maven.skins</groupId>
<artifactId>maven-fluido-skin</artifactId>
<version>1.3.1</version>
</skin>
<bannerLeft>
<name>Apache Software Foundation</name>
<src>http://www.apache.org/images/asf-logo.gif</src>
<href>http://www.apache.org/</href>
</bannerLeft>
<bannerRight>
<name>Apache Struts</name>
<src>http://struts.apache.org/img/struts-logo.svg</src>
<href>http://struts.apache.org/</href>
</bannerRight>
<publishDate position="none"/>
<version position="none"/>
<body>
<links>
<item name="Apache" href="http://www.apache.org/"/>
<item name="Struts" href="http://struts.apache.org/"/>
</links>
<menu ref="parent"/>
<menu ref="reports"/>
<footer>
<div class="row span12">
Apache Struts, Struts, Apache, the Apache feather logo, and the Apache Struts
project logos are trademarks of The Apache Software Foundation.
</div>
</footer>
</body>
</project>
+11
View File
@@ -0,0 +1,11 @@
= Struts 2 Java 8 Support plugin
This plugin aims to add support for Java 8 specific features.
As Struts 2 core targets Java 6/7 and some features won't work and they have to be adjusted.
Below is a list of features supported by this plugin
== Supported Java 8 features
- Lambada expressions in actions when using them with the Convention plugin
== Installation
Just drop this plugin into `WEB-INF/lib` folder or add it as Maven dependency
+60
View File
@@ -0,0 +1,60 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>2.3.22</version>
</parent>
<artifactId>struts2-java8-support-plugin</artifactId>
<packaging>jar</packaging>
<name>Struts 2 Java 8 support plugin</name>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-Activator>org.apache.struts2.osgi.StrutsActivator</Bundle-Activator>
<manifestLocation>META-INF</manifestLocation>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.apache.struts.xwork</groupId>
<artifactId>xwork-core</artifactId>
<exclusions>
<exclusion>
<groupId>asm</groupId>
<artifactId>asm</artifactId>
</exclusion>
<exclusion>
<groupId>asm</groupId>
<artifactId>asm-commons</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
</dependency>
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm-commons</artifactId>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
@@ -0,0 +1,585 @@
/*
* Copyright 2002-2003,2009 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.struts2.convention;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.FileManager;
import com.opensymphony.xwork2.FileManagerFactory;
import com.opensymphony.xwork2.XWorkException;
import com.opensymphony.xwork2.util.finder.ClassFinder;
import com.opensymphony.xwork2.util.finder.ClassLoaderInterface;
import com.opensymphony.xwork2.util.finder.Test;
import com.opensymphony.xwork2.util.logging.Logger;
import com.opensymphony.xwork2.util.logging.LoggerFactory;
import org.apache.commons.lang3.StringUtils;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
/**
* Copy of {@link com.opensymphony.xwork2.util.finder.DefaultClassFinder} with proper support for Java8
*/
public class Java8ClassFinder implements ClassFinder {
private static final Logger LOG = LoggerFactory.getLogger(Java8ClassFinder.class);
private final Map<String, List<Info>> annotated = new HashMap<String, List<Info>>();
private final Map<String, ClassInfo> classInfos = new LinkedHashMap<String, ClassInfo>();
private final List<String> classesNotLoaded = new ArrayList<String>();
private boolean extractBaseInterfaces;
private ClassLoaderInterface classLoaderInterface;
private FileManager fileManager;
public Java8ClassFinder(ClassLoaderInterface classLoaderInterface, Collection<URL> urls, boolean extractBaseInterfaces, Set<String> protocols, Test<String> classNameFilter) {
this.classLoaderInterface = classLoaderInterface;
this.extractBaseInterfaces = extractBaseInterfaces;
this.fileManager = ActionContext.getContext().getInstance(FileManagerFactory.class).getFileManager();
List<String> classNames = new ArrayList<String>();
for (URL location : urls) {
try {
if (protocols.contains(location.getProtocol())) {
classNames.addAll(jar(location));
} else if ("file".equals(location.getProtocol())) {
try {
// See if it's actually a jar
URL jarUrl = new URL("jar", "", location.toExternalForm() + "!/");
JarURLConnection juc = (JarURLConnection) jarUrl.openConnection();
juc.getJarFile();
classNames.addAll(jar(jarUrl));
} catch (IOException e) {
classNames.addAll(file(location));
}
}
} catch (Exception e) {
if (LOG.isErrorEnabled())
LOG.error("Unable to read URL [#0]", e, location.toExternalForm());
}
}
for (String className : classNames) {
try {
if (classNameFilter.test(className))
readClassDef(className);
} catch (Throwable e) {
if (LOG.isErrorEnabled())
LOG.error("Unable to read class [#0]", e, className);
}
}
}
public Java8ClassFinder(Class... classes){
this(Arrays.asList(classes));
}
public Java8ClassFinder(List<Class> classes){
this.classLoaderInterface = null;
List<Info> infos = new ArrayList<Info>();
List<Package> packages = new ArrayList<Package>();
for (Class clazz : classes) {
Package aPackage = clazz.getPackage();
if (aPackage != null && !packages.contains(aPackage)){
infos.add(new PackageInfo(aPackage));
packages.add(aPackage);
}
ClassInfo classInfo = new ClassInfo(clazz, this);
infos.add(classInfo);
classInfos.put(classInfo.getName(), classInfo);
for (Method method : clazz.getDeclaredMethods()) {
infos.add(new MethodInfo(classInfo, method));
}
for (Constructor constructor : clazz.getConstructors()) {
infos.add(new MethodInfo(classInfo, constructor));
}
for (Field field : clazz.getDeclaredFields()) {
infos.add(new FieldInfo(classInfo, field));
}
}
for (Info info : infos) {
for (AnnotationInfo annotation : info.getAnnotations()) {
List<Info> annotationInfos = getAnnotationInfos(annotation.getName());
annotationInfos.add(info);
}
}
}
public ClassLoaderInterface getClassLoaderInterface() {
return classLoaderInterface;
}
public boolean isAnnotationPresent(Class<? extends Annotation> annotation) {
List<Info> infos = annotated.get(annotation.getName());
return infos != null && !infos.isEmpty();
}
public List<String> getClassesNotLoaded() {
return Collections.unmodifiableList(classesNotLoaded);
}
public List<Package> findAnnotatedPackages(Class<? extends Annotation> annotation) {
classesNotLoaded.clear();
List<Package> packages = new ArrayList<Package>();
List<Info> infos = getAnnotationInfos(annotation.getName());
for (Info info : infos) {
if (info instanceof PackageInfo) {
PackageInfo packageInfo = (PackageInfo) info;
try {
Package pkg = packageInfo.get();
// double check via proper reflection
if (pkg.isAnnotationPresent(annotation)) {
packages.add(pkg);
}
} catch (ClassNotFoundException e) {
classesNotLoaded.add(packageInfo.getName());
}
}
}
return packages;
}
public List<Class> findAnnotatedClasses(Class<? extends Annotation> annotation) {
classesNotLoaded.clear();
List<Class> classes = new ArrayList<Class>();
List<Info> infos = getAnnotationInfos(annotation.getName());
for (Info info : infos) {
if (info instanceof ClassInfo) {
ClassInfo classInfo = (ClassInfo) info;
try {
Class clazz = classInfo.get();
// double check via proper reflection
if (clazz.isAnnotationPresent(annotation)) {
classes.add(clazz);
}
} catch (Throwable e) {
if (LOG.isErrorEnabled())
LOG.error("Error loading class [#0]", e, classInfo.getName());
classesNotLoaded.add(classInfo.getName());
}
}
}
return classes;
}
public List<Method> findAnnotatedMethods(Class<? extends Annotation> annotation) {
classesNotLoaded.clear();
List<ClassInfo> seen = new ArrayList<ClassInfo>();
List<Method> methods = new ArrayList<Method>();
List<Info> infos = getAnnotationInfos(annotation.getName());
for (Info info : infos) {
if (info instanceof MethodInfo && !"<init>".equals(info.getName())) {
MethodInfo methodInfo = (MethodInfo) info;
ClassInfo classInfo = methodInfo.getDeclaringClass();
if (seen.contains(classInfo)) continue;
seen.add(classInfo);
try {
Class clazz = classInfo.get();
for (Method method : clazz.getDeclaredMethods()) {
if (method.isAnnotationPresent(annotation)) {
methods.add(method);
}
}
} catch (Throwable e) {
if (LOG.isErrorEnabled())
LOG.error("Error loading class [#0]", e, classInfo.getName());
classesNotLoaded.add(classInfo.getName());
}
}
}
return methods;
}
public List<Constructor> findAnnotatedConstructors(Class<? extends Annotation> annotation) {
classesNotLoaded.clear();
List<ClassInfo> seen = new ArrayList<ClassInfo>();
List<Constructor> constructors = new ArrayList<Constructor>();
List<Info> infos = getAnnotationInfos(annotation.getName());
for (Info info : infos) {
if (info instanceof MethodInfo && "<init>".equals(info.getName())) {
MethodInfo methodInfo = (MethodInfo) info;
ClassInfo classInfo = methodInfo.getDeclaringClass();
if (seen.contains(classInfo)) continue;
seen.add(classInfo);
try {
Class clazz = classInfo.get();
for (Constructor constructor : clazz.getConstructors()) {
if (constructor.isAnnotationPresent(annotation)) {
constructors.add(constructor);
}
}
} catch (Throwable e) {
if (LOG.isErrorEnabled())
LOG.error("Error loading class [#0]", e, classInfo.getName());
classesNotLoaded.add(classInfo.getName());
}
}
}
return constructors;
}
public List<Field> findAnnotatedFields(Class<? extends Annotation> annotation) {
classesNotLoaded.clear();
List<ClassInfo> seen = new ArrayList<ClassInfo>();
List<Field> fields = new ArrayList<Field>();
List<Info> infos = getAnnotationInfos(annotation.getName());
for (Info info : infos) {
if (info instanceof FieldInfo) {
FieldInfo fieldInfo = (FieldInfo) info;
ClassInfo classInfo = fieldInfo.getDeclaringClass();
if (seen.contains(classInfo)) continue;
seen.add(classInfo);
try {
Class clazz = classInfo.get();
for (Field field : clazz.getDeclaredFields()) {
if (field.isAnnotationPresent(annotation)) {
fields.add(field);
}
}
} catch (Throwable e) {
if (LOG.isErrorEnabled())
LOG.error("Error loading class [#0]", e, classInfo.getName());
classesNotLoaded.add(classInfo.getName());
}
}
}
return fields;
}
public List<Class> findClassesInPackage(String packageName, boolean recursive) {
classesNotLoaded.clear();
List<Class> classes = new ArrayList<Class>();
for (ClassInfo classInfo : classInfos.values()) {
try {
if (recursive && classInfo.getPackageName().startsWith(packageName)){
classes.add(classInfo.get());
} else if (classInfo.getPackageName().equals(packageName)){
classes.add(classInfo.get());
}
} catch (Throwable e) {
if (LOG.isErrorEnabled())
LOG.error("Error loading class [#0]", e, classInfo.getName());
classesNotLoaded.add(classInfo.getName());
}
}
return classes;
}
public List<Class> findClasses(Test<ClassInfo> test) {
classesNotLoaded.clear();
List<Class> classes = new ArrayList<Class>();
for (ClassInfo classInfo : classInfos.values()) {
try {
if (test.test(classInfo)) {
classes.add(classInfo.get());
}
} catch (Throwable e) {
if (LOG.isErrorEnabled())
LOG.error("Error loading class [#0]", e, classInfo.getName());
classesNotLoaded.add(classInfo.getName());
}
}
return classes;
}
public List<Class> findClasses() {
classesNotLoaded.clear();
List<Class> classes = new ArrayList<Class>();
for (ClassInfo classInfo : classInfos.values()) {
try {
classes.add(classInfo.get());
} catch (Throwable e) {
if (LOG.isErrorEnabled())
LOG.error("Error loading class [#0]", e, classInfo.getName());
classesNotLoaded.add(classInfo.getName());
}
}
return classes;
}
private static List<URL> getURLs(ClassLoaderInterface classLoader, String[] dirNames) {
List<URL> urls = new ArrayList<URL>();
for (String dirName : dirNames) {
try {
Enumeration<URL> classLoaderURLs = classLoader.getResources(dirName);
while (classLoaderURLs.hasMoreElements()) {
URL url = classLoaderURLs.nextElement();
urls.add(url);
}
} catch (IOException ioe) {
if (LOG.isErrorEnabled())
LOG.error("Could not read driectory [#0]", ioe, dirName);
}
}
return urls;
}
private List<String> file(URL location) {
List<String> classNames = new ArrayList<String>();
File dir = new File(URLDecoder.decode(location.getPath()));
if ("META-INF".equals(dir.getName())) {
dir = dir.getParentFile(); // Scrape "META-INF" off
}
if (dir.isDirectory()) {
scanDir(dir, classNames, "");
}
return classNames;
}
private void scanDir(File dir, List<String> classNames, String packageName) {
File[] files = dir.listFiles();
for (File file : files) {
if (file.isDirectory()) {
scanDir(file, classNames, packageName + file.getName() + ".");
} else if (file.getName().endsWith(".class")) {
String name = file.getName();
name = name.replaceFirst(".class$", "");
// Classes packaged in an exploded .war (e.g. in a VFS file system) should not
// have WEB-INF.classes in their package name.
classNames.add(StringUtils.removeStart(packageName, "WEB-INF.classes.") + name);
}
}
}
private List<String> jar(URL location) throws IOException {
URL url = fileManager.normalizeToFileProtocol(location);
if (url != null) {
InputStream in = url.openStream();
try {
JarInputStream jarStream = new JarInputStream(in);
return jar(jarStream);
} finally {
in.close();
}
} else if (LOG.isDebugEnabled())
LOG.debug("Unable to read [#0]", location.toExternalForm());
return Collections.emptyList();
}
private List<String> jar(JarInputStream jarStream) throws IOException {
List<String> classNames = new ArrayList<String>();
JarEntry entry;
while ((entry = jarStream.getNextJarEntry()) != null) {
if (entry.isDirectory() || !entry.getName().endsWith(".class")) {
continue;
}
String className = entry.getName();
className = className.replaceFirst(".class$", "");
//war files are treated as .jar files, so takeout WEB-INF/classes
className = StringUtils.removeStart(className, "WEB-INF/classes/");
className = className.replace('/', '.');
classNames.add(className);
}
return classNames;
}
private List<Info> getAnnotationInfos(String name) {
List<Info> infos = annotated.get(name);
if (infos == null) {
infos = new ArrayList<Info>();
annotated.put(name, infos);
}
return infos;
}
private void readClassDef(String className) {
if (!className.endsWith(".class")) {
className = className.replace('.', '/') + ".class";
}
try {
URL resource = classLoaderInterface.getResource(className);
if (resource != null) {
InputStream in = resource.openStream();
try {
ClassReader classReader = new ClassReader(in);
classReader.accept(new InfoBuildingClassVisitor(this), ClassReader.SKIP_DEBUG);
} finally {
in.close();
}
} else {
throw new XWorkException("Could not load " + className);
}
} catch (IOException e) {
throw new XWorkException("Could not load " + className, e);
}
}
public class InfoBuildingClassVisitor extends ClassVisitor {
private Info info;
private ClassFinder classFinder;
public InfoBuildingClassVisitor(ClassFinder classFinder) {
super(Opcodes.ASM5);
this.classFinder = classFinder;
}
public InfoBuildingClassVisitor(Info info, ClassFinder classFinder) {
this(classFinder);
this.info = info;
}
@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
if (name.endsWith("package-info")) {
info = new PackageInfo(javaName(name), classFinder);
} else {
ClassInfo classInfo = new ClassInfo(javaName(name), javaName(superName), classFinder);
for (String interfce : interfaces) {
classInfo.getInterfaces().add(javaName(interfce));
}
info = classInfo;
classInfos.put(classInfo.getName(), classInfo);
if (extractBaseInterfaces)
extractSuperInterfaces(classInfo);
}
}
private void extractSuperInterfaces(ClassInfo classInfo) {
String superType = classInfo.getSuperType();
if (superType != null) {
ClassInfo base = classInfos.get(superType);
if (base == null) {
//try to load base
String resource = superType.replace('.', '/') + ".class";
readClassDef(resource);
base = classInfos.get(superType);
}
if (base != null) {
List<String> interfaces = classInfo.getSuperInterfaces();
interfaces.addAll(base.getSuperInterfaces());
interfaces.addAll(base.getInterfaces());
}
}
}
private String javaName(String name) {
return (name == null)? null:name.replace('/', '.');
}
@Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
AnnotationInfo annotationInfo = new AnnotationInfo(desc);
info.getAnnotations().add(annotationInfo);
getAnnotationInfos(annotationInfo.getName()).add(info);
return null;
}
@Override
public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
ClassInfo classInfo = ((ClassInfo) info);
FieldInfo fieldInfo = new FieldInfo(classInfo, name, desc);
classInfo.getFields().add(fieldInfo);
return null;
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
ClassInfo classInfo = ((ClassInfo) info);
MethodInfo methodInfo = new MethodInfo(classInfo, name, desc);
classInfo.getMethods().add(methodInfo);
return new InfoBuildingMethodVisitor(methodInfo);
}
}
public class InfoBuildingMethodVisitor extends MethodVisitor {
private Info info;
public InfoBuildingMethodVisitor() {
super(Opcodes.ASM5);
}
public InfoBuildingMethodVisitor(Info info) {
this();
this.info = info;
}
@Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
AnnotationInfo annotationInfo = new AnnotationInfo(desc);
info.getAnnotations().add(annotationInfo);
getAnnotationInfos(annotationInfo.getName()).add(info);
return null;
}
@Override
public AnnotationVisitor visitParameterAnnotation(int param, String desc, boolean visible) {
MethodInfo methodInfo = ((MethodInfo) info);
List<AnnotationInfo> annotationInfos = methodInfo.getParameterAnnotations(param);
AnnotationInfo annotationInfo = new AnnotationInfo(desc);
annotationInfos.add(annotationInfo);
return null;
}
}
private static final class DefaultClassnameFilterImpl implements Test<String> {
public boolean test(String className) {
return true;
}
}
}
@@ -0,0 +1,48 @@
/*
* Copyright 2002-2003,2009 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.struts2.convention;
import com.opensymphony.xwork2.util.finder.ClassFinder;
import com.opensymphony.xwork2.util.finder.ClassFinderFactory;
import com.opensymphony.xwork2.util.finder.ClassLoaderInterface;
import com.opensymphony.xwork2.util.finder.Test;
import com.opensymphony.xwork2.util.logging.Logger;
import com.opensymphony.xwork2.util.logging.LoggerFactory;
import java.net.URL;
import java.util.Collection;
import java.util.Set;
public class Java8ClassFinderFactory implements ClassFinderFactory {
private static final Logger LOG = LoggerFactory.getLogger(Java8ClassFinderFactory.class);
public Java8ClassFinderFactory() {
try {
LOG.trace("Checking if ASM5 is on the classpath....");
Class.forName("org.objectweb.asm.MethodVisitor");
LOG.trace("Proper version of ASM5 is in use!");
} catch (ClassNotFoundException e) {
LOG.warn("ASM5 is missing or older version is used! If you use Maven, please exclude asm.jar and asm-commons.jar version 3 from xwork!");
}
}
public ClassFinder buildClassFinder(ClassLoaderInterface classLoaderInterface, Collection<URL> urls, boolean extractBaseInterfaces, Set<String> protocols, Test<String> classNameFilter) {
LOG.debug("Creating new instance of Java8ClassFinder");
return new Java8ClassFinder(classLoaderInterface, urls, extractBaseInterfaces, protocols, classNameFilter);
}
}
@@ -0,0 +1,174 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
@@ -0,0 +1,5 @@
Apache Struts
Copyright 2000-2011 The Apache Software Foundation
This product includes software developed by
The Apache Software Foundation (http://www.apache.org/).
@@ -1,4 +1,4 @@
<?xml version="1.0"?>
<?xml version="1.0" encoding="UTF-8" ?>
<!--
/*
* $Id$
@@ -21,26 +21,13 @@
* under the License.
*/
-->
<!--
// ======================================================================== 78
-->
<document>
<properties>
<title>Source Xref report</title>
</properties>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<body>
<struts order="25">
<section name="Struts 2 - Source Xref">
<bean type="com.opensymphony.xwork2.util.finder.ClassFinderFactory" class="org.apache.struts2.convention.Java8ClassFinderFactory" scope="singleton"/>
<ul>
<li>
<a href="struts-core/jxr.html" target="_blank">
Struts Core</a></li>
</ul>
</section>
</body>
</document>
</struts>
+57
View File
@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
-->
<project name="Struts 2">
<skin>
<groupId>org.apache.maven.skins</groupId>
<artifactId>maven-fluido-skin</artifactId>
<version>1.3.1</version>
</skin>
<bannerLeft>
<name>Apache Software Foundation</name>
<src>http://www.apache.org/images/asf-logo.gif</src>
<href>http://www.apache.org/</href>
</bannerLeft>
<bannerRight>
<name>Apache Struts</name>
<src>http://struts.apache.org/img/struts-logo.svg</src>
<href>http://struts.apache.org/</href>
</bannerRight>
<publishDate position="none"/>
<version position="none"/>
<body>
<links>
<item name="Apache" href="http://www.apache.org/"/>
<item name="Struts" href="http://struts.apache.org/"/>
</links>
<menu ref="parent"/>
<menu ref="reports"/>
<footer>
<div class="row span12">
Apache Struts, Struts, Apache, the Apache feather logo, and the Apache Struts
project logos are trademarks of The Apache Software Foundation.
</div>
</footer>
</body>
</project>
+1 -1
View File
@@ -25,7 +25,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>2.3.19</version>
<version>2.3.22</version>
</parent>
<artifactId>struts2-javatemplates-plugin</artifactId>
@@ -53,7 +53,9 @@ public class SubmitHandler extends AbstractTagHandler implements TagGenerator {
.addIfExists("alt", params.get("label"))
.addIfExists("id", params.get("id"))
.addIfExists("class", params.get("cssClass"))
.addIfExists("style", params.get("cssStyle"));
.addIfExists("style", params.get("cssStyle"))
.addIfExists("title", params.get("title"));
start("input", attrs);
} else {
attrs.addIfExists("name", params.get("name"))
+57
View File
@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
-->
<project name="Struts 2">
<skin>
<groupId>org.apache.maven.skins</groupId>
<artifactId>maven-fluido-skin</artifactId>
<version>1.3.1</version>
</skin>
<bannerLeft>
<name>Apache Software Foundation</name>
<src>http://www.apache.org/images/asf-logo.gif</src>
<href>http://www.apache.org/</href>
</bannerLeft>
<bannerRight>
<name>Apache Struts</name>
<src>http://struts.apache.org/img/struts-logo.svg</src>
<href>http://struts.apache.org/</href>
</bannerRight>
<publishDate position="none"/>
<version position="none"/>
<body>
<links>
<item name="Apache" href="http://www.apache.org/"/>
<item name="Struts" href="http://struts.apache.org/"/>
</links>
<menu ref="parent"/>
<menu ref="reports"/>
<footer>
<div class="row span12">
Apache Struts, Struts, Apache, the Apache feather logo, and the Apache Struts
project logos are trademarks of The Apache Software Foundation.
</div>
</footer>
</body>
</project>
+1 -1
View File
@@ -26,7 +26,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>2.3.19</version>
<version>2.3.22</version>
</parent>
<artifactId>struts2-jfreechart-plugin</artifactId>
+57
View File
@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
-->
<project name="Struts 2">
<skin>
<groupId>org.apache.maven.skins</groupId>
<artifactId>maven-fluido-skin</artifactId>
<version>1.3.1</version>
</skin>
<bannerLeft>
<name>Apache Software Foundation</name>
<src>http://www.apache.org/images/asf-logo.gif</src>
<href>http://www.apache.org/</href>
</bannerLeft>
<bannerRight>
<name>Apache Struts</name>
<src>http://struts.apache.org/img/struts-logo.svg</src>
<href>http://struts.apache.org/</href>
</bannerRight>
<publishDate position="none"/>
<version position="none"/>
<body>
<links>
<item name="Apache" href="http://www.apache.org/"/>
<item name="Struts" href="http://struts.apache.org/"/>
</links>
<menu ref="parent"/>
<menu ref="reports"/>
<footer>
<div class="row span12">
Apache Struts, Struts, Apache, the Apache feather logo, and the Apache Struts
project logos are trademarks of The Apache Software Foundation.
</div>
</footer>
</body>
</project>
+1 -1
View File
@@ -26,7 +26,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>2.3.19</version>
<version>2.3.22</version>
</parent>
<artifactId>struts2-jsf-plugin</artifactId>
+57
View File
@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
-->
<project name="Struts 2">
<skin>
<groupId>org.apache.maven.skins</groupId>
<artifactId>maven-fluido-skin</artifactId>
<version>1.3.1</version>
</skin>
<bannerLeft>
<name>Apache Software Foundation</name>
<src>http://www.apache.org/images/asf-logo.gif</src>
<href>http://www.apache.org/</href>
</bannerLeft>
<bannerRight>
<name>Apache Struts</name>
<src>http://struts.apache.org/img/struts-logo.svg</src>
<href>http://struts.apache.org/</href>
</bannerRight>
<publishDate position="none"/>
<version position="none"/>
<body>
<links>
<item name="Apache" href="http://www.apache.org/"/>
<item name="Struts" href="http://struts.apache.org/"/>
</links>
<menu ref="parent"/>
<menu ref="reports"/>
<footer>
<div class="row span12">
Apache Struts, Struts, Apache, the Apache feather logo, and the Apache Struts
project logos are trademarks of The Apache Software Foundation.
</div>
</footer>
</body>
</project>
+1 -1
View File
@@ -26,7 +26,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>2.3.19</version>
<version>2.3.22</version>
</parent>
<artifactId>struts2-json-plugin</artifactId>
@@ -87,8 +87,8 @@ public class JSONInterceptor extends AbstractInterceptor {
}
Object rootObject = null;
final ValueStack stack = invocation.getStack();
if (this.root != null) {
ValueStack stack = invocation.getStack();
rootObject = stack.findValue(this.root);
if (rootObject == null) {
@@ -100,6 +100,26 @@ public class JSONInterceptor extends AbstractInterceptor {
// load JSON object
Object obj = JSONUtil.deserialize(request.getReader());
// JSON array (this.root cannot be null in this case)
if(obj instanceof List && this.root != null) {
String mapKey = this.root;
rootObject = null;
if(this.root.indexOf('.') != -1) {
mapKey = this.root.substring(this.root.lastIndexOf('.') + 1);
rootObject = stack.findValue(this.root.substring(0, this.root.lastIndexOf('.')));
if (rootObject == null) {
throw new RuntimeException("JSON array: Invalid root expression: '" + this.root + "'.");
}
}
// create a map with a list inside
Map m = new HashMap();
m.put(mapKey, new ArrayList((List) obj));
obj = m;
}
if (obj instanceof Map) {
Map json = (Map) obj;
@@ -305,7 +305,18 @@ public class JSONWriter {
} catch (Exception ex) {
LOG.debug(ex.getMessage(), ex);
}
} else {
//in hibernate4.3.7,because javassist3.18.1's class name generate rule is '_$$_jvst'+...
} else if(clazz.getName().contains("$$_jvst")){
try {
baseAccessor = Class.forName(
clazz.getName().substring(0, clazz.getName().indexOf("_$$")))
.getMethod(accessor.getName(), accessor.getParameterTypes());
} catch (Exception ex) {
LOG.debug(ex.getMessage(), ex);
}
}
else {
return accessor;
}
return baseAccessor;
+57
View File
@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
-->
<project name="Struts 2">
<skin>
<groupId>org.apache.maven.skins</groupId>
<artifactId>maven-fluido-skin</artifactId>
<version>1.3.1</version>
</skin>
<bannerLeft>
<name>Apache Software Foundation</name>
<src>http://www.apache.org/images/asf-logo.gif</src>
<href>http://www.apache.org/</href>
</bannerLeft>
<bannerRight>
<name>Apache Struts</name>
<src>http://struts.apache.org/img/struts-logo.svg</src>
<href>http://struts.apache.org/</href>
</bannerRight>
<publishDate position="none"/>
<version position="none"/>
<body>
<links>
<item name="Apache" href="http://www.apache.org/"/>
<item name="Struts" href="http://struts.apache.org/"/>
</links>
<menu ref="parent"/>
<menu ref="reports"/>
<footer>
<div class="row span12">
Apache Struts, Struts, Apache, the Apache feather logo, and the Apache Struts
project logos are trademarks of The Apache Software Foundation.
</div>
</footer>
</body>
</project>
@@ -0,0 +1,32 @@
package org.apache.struts2.json;
import java.util.ArrayList;
import java.util.List;
public class AnotherBean {
private List<Bean> beans;
private AnotherBean yetAnotherBean;
public List<Bean> getBeans() {
if (this.beans == null) {
this.beans = new ArrayList<Bean>();
}
return this.beans;
}
public void setBeans(List<Bean> beans) {
this.beans = beans;
}
public AnotherBean getYetAnotherBean() {
if(this.yetAnotherBean == null) {
this.yetAnotherBean = new AnotherBean();
}
return yetAnotherBean;
}
public void setYetAnotherBean(AnotherBean yetAnotherBean) {
this.yetAnotherBean = yetAnotherBean;
}
}
@@ -459,7 +459,59 @@ public class JSONInterceptorTest extends StrutsTestCase {
assertEquals(bean2.getDoubleField(), 10.1);
assertEquals(bean2.getByteField(), 3);
}
public void testJSONArray() throws Exception {
setRequestContent("json-12.txt");
this.request.addHeader("content-type", "application/json");
// interceptor
JSONInterceptor interceptor = new JSONInterceptor();
interceptor.setRoot("beans");
TestAction5 action = new TestAction5();
this.invocation.setAction(action);
this.invocation.getStack().push(action);
interceptor.intercept(this.invocation);
List<Bean> beans = action.getBeans();
assertNotNull(beans);
assertEquals(1, beans.size());
assertTrue(beans.get(0).isBooleanField());
assertEquals(beans.get(0).getStringField(), "test");
assertEquals(beans.get(0).getIntField(), 10);
assertEquals(beans.get(0).getCharField(), 's');
assertEquals(beans.get(0).getDoubleField(), 10.1);
assertEquals(beans.get(0).getByteField(), 3);
}
public void testJSONArray2() throws Exception {
setRequestContent("json-12.txt");
this.request.addHeader("content-type", "application/json");
// interceptor
JSONInterceptor interceptor = new JSONInterceptor();
interceptor.setRoot("anotherBean.yetAnotherBean.beans");
TestAction5 action = new TestAction5();
this.invocation.setAction(action);
this.invocation.getStack().push(action);
interceptor.intercept(this.invocation);
List<Bean> beans = action.getAnotherBean().getYetAnotherBean().getBeans();
assertNotNull(beans);
assertEquals(1, beans.size());
assertTrue(beans.get(0).isBooleanField());
assertEquals(beans.get(0).getStringField(), "test");
assertEquals(beans.get(0).getIntField(), 10);
assertEquals(beans.get(0).getCharField(), 's');
assertEquals(beans.get(0).getDoubleField(), 10.1);
assertEquals(beans.get(0).getByteField(), 3);
}
@Override
protected void setUp() throws Exception {
super.setUp();
@@ -0,0 +1,52 @@
/*
* $Id$
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.struts2.json;
import java.util.ArrayList;
import java.util.List;
public class TestAction5 {
private List<Bean> beans;
private AnotherBean anotherBean;
public List<Bean> getBeans() {
if (this.beans == null) {
this.beans = new ArrayList<Bean>();
}
return this.beans;
}
public void setBeans(List<Bean> beans) {
this.beans = beans;
}
public AnotherBean getAnotherBean() {
if(this.anotherBean == null) {
this.anotherBean = new AnotherBean();
}
return anotherBean;
}
public void setAnotherBean(AnotherBean anotherBean) {
this.anotherBean = anotherBean;
}
}
@@ -0,0 +1,8 @@
[{
"booleanField": true,
"stringField" : "test",
"intField" : 10,
"charField": "s",
"doubleField": 10.1,
"byteField": 3
}]
+1 -1
View File
@@ -26,7 +26,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>2.3.19</version>
<version>2.3.22</version>
</parent>
<artifactId>struts2-junit-plugin</artifactId>
+57
View File
@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
-->
<project name="Struts 2">
<skin>
<groupId>org.apache.maven.skins</groupId>
<artifactId>maven-fluido-skin</artifactId>
<version>1.3.1</version>
</skin>
<bannerLeft>
<name>Apache Software Foundation</name>
<src>http://www.apache.org/images/asf-logo.gif</src>
<href>http://www.apache.org/</href>
</bannerLeft>
<bannerRight>
<name>Apache Struts</name>
<src>http://struts.apache.org/img/struts-logo.svg</src>
<href>http://struts.apache.org/</href>
</bannerRight>
<publishDate position="none"/>
<version position="none"/>
<body>
<links>
<item name="Apache" href="http://www.apache.org/"/>
<item name="Struts" href="http://struts.apache.org/"/>
</links>
<menu ref="parent"/>
<menu ref="reports"/>
<footer>
<div class="row span12">
Apache Struts, Struts, Apache, the Apache feather logo, and the Apache Struts
project logos are trademarks of The Apache Software Foundation.
</div>
</footer>
</body>
</project>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>2.3.19</version>
<version>2.3.22</version>
</parent>
<artifactId>struts2-osgi-plugin</artifactId>

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