From ac107d0c2ae939c669ba086c2874d02790519b06 Mon Sep 17 00:00:00 2001 From: Chris Beams Date: Tue, 13 Dec 2011 16:35:49 +0000 Subject: [PATCH 01/22] Release Spring Framework 3.1.0.RELEASE --- build.properties | 6 +++--- org.springframework.aop/pom.xml | 4 ++-- org.springframework.asm/pom.xml | 4 ++-- org.springframework.aspects/pom.xml | 4 ++-- org.springframework.beans/pom.xml | 4 ++-- org.springframework.context.support/pom.xml | 4 ++-- org.springframework.context/pom.xml | 4 ++-- org.springframework.core/pom.xml | 4 ++-- org.springframework.expression/pom.xml | 4 ++-- org.springframework.instrument.tomcat/pom.xml | 4 ++-- org.springframework.instrument/pom.xml | 4 ++-- org.springframework.integration-tests/pom.xml | 4 ++-- org.springframework.jdbc/pom.xml | 4 ++-- org.springframework.jms/pom.xml | 4 ++-- org.springframework.orm/pom.xml | 4 ++-- org.springframework.oxm/pom.xml | 4 ++-- org.springframework.spring-library/pom.xml | 2 +- org.springframework.spring-parent/pom.xml | 2 +- org.springframework.test/pom.xml | 4 ++-- org.springframework.transaction/pom.xml | 4 ++-- org.springframework.web.portlet/pom.xml | 4 ++-- org.springframework.web.servlet/pom.xml | 4 ++-- org.springframework.web.struts/pom.xml | 4 ++-- org.springframework.web/pom.xml | 4 ++-- 24 files changed, 47 insertions(+), 47 deletions(-) diff --git a/build.properties b/build.properties index 2bcbd2ec222..5f7d08a8dca 100644 --- a/build.properties +++ b/build.properties @@ -17,13 +17,13 @@ spring.osgi.range="${spring.osgi.range.nq}" aj.osgi.range="[1.6.8, 2.0.0)" ## For GA releases -#release.type=release -#build.stamp=RELEASE +release.type=release +build.stamp=RELEASE ## For milestone releases #release.type=milestone #build.stamp=M1 ## For trunk development / ci builds -release.type=integration +#release.type=integration #build.stamp=BUILD-SNAPSHOT diff --git a/org.springframework.aop/pom.xml b/org.springframework.aop/pom.xml index 98c0cf409d4..d21357bb2ff 100644 --- a/org.springframework.aop/pom.xml +++ b/org.springframework.aop/pom.xml @@ -4,12 +4,12 @@ org.springframework spring-aop jar - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE org.springframework spring-parent ../org.springframework.spring-parent - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE diff --git a/org.springframework.asm/pom.xml b/org.springframework.asm/pom.xml index 5b66af1639b..789e6ef3dae 100644 --- a/org.springframework.asm/pom.xml +++ b/org.springframework.asm/pom.xml @@ -4,12 +4,12 @@ org.springframework spring-asm jar - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE org.springframework spring-parent ../org.springframework.spring-parent - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE diff --git a/org.springframework.aspects/pom.xml b/org.springframework.aspects/pom.xml index d5fa43e4e9c..5feff8a29d0 100644 --- a/org.springframework.aspects/pom.xml +++ b/org.springframework.aspects/pom.xml @@ -4,12 +4,12 @@ org.springframework spring-aspects jar - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE org.springframework spring-parent ../org.springframework.spring-parent - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE diff --git a/org.springframework.beans/pom.xml b/org.springframework.beans/pom.xml index 67ae140c827..664a729e864 100644 --- a/org.springframework.beans/pom.xml +++ b/org.springframework.beans/pom.xml @@ -4,12 +4,12 @@ org.springframework spring-beans jar - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE org.springframework spring-parent ../org.springframework.spring-parent - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE diff --git a/org.springframework.context.support/pom.xml b/org.springframework.context.support/pom.xml index 9a4eb62d39d..5017fbf1732 100644 --- a/org.springframework.context.support/pom.xml +++ b/org.springframework.context.support/pom.xml @@ -4,12 +4,12 @@ org.springframework spring-context-support jar - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE org.springframework spring-parent ../org.springframework.spring-parent - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE diff --git a/org.springframework.context/pom.xml b/org.springframework.context/pom.xml index 2fba91849ac..3d77ff69fc8 100644 --- a/org.springframework.context/pom.xml +++ b/org.springframework.context/pom.xml @@ -6,12 +6,12 @@ org.springframework spring-context jar - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE org.springframework spring-parent ../org.springframework.spring-parent - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE diff --git a/org.springframework.core/pom.xml b/org.springframework.core/pom.xml index 1717f2c84d0..85f51005548 100644 --- a/org.springframework.core/pom.xml +++ b/org.springframework.core/pom.xml @@ -6,12 +6,12 @@ org.springframework spring-core jar - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE org.springframework spring-parent ../org.springframework.spring-parent - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE diff --git a/org.springframework.expression/pom.xml b/org.springframework.expression/pom.xml index 1ac99341d02..67a3902ae6b 100644 --- a/org.springframework.expression/pom.xml +++ b/org.springframework.expression/pom.xml @@ -4,12 +4,12 @@ org.springframework spring-expression jar - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE org.springframework spring-parent ../org.springframework.spring-parent - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE diff --git a/org.springframework.instrument.tomcat/pom.xml b/org.springframework.instrument.tomcat/pom.xml index bf94631dfbc..113421d663a 100644 --- a/org.springframework.instrument.tomcat/pom.xml +++ b/org.springframework.instrument.tomcat/pom.xml @@ -4,12 +4,12 @@ org.springframework spring-instrument-tomcat jar - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE org.springframework spring-parent ../org.springframework.spring-parent - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE diff --git a/org.springframework.instrument/pom.xml b/org.springframework.instrument/pom.xml index c7b4d47fe8c..0069efc1a56 100644 --- a/org.springframework.instrument/pom.xml +++ b/org.springframework.instrument/pom.xml @@ -4,12 +4,12 @@ org.springframework spring-instrument jar - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE org.springframework spring-parent ../org.springframework.spring-parent - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE diff --git a/org.springframework.integration-tests/pom.xml b/org.springframework.integration-tests/pom.xml index 48316c16b67..5eff89a392e 100644 --- a/org.springframework.integration-tests/pom.xml +++ b/org.springframework.integration-tests/pom.xml @@ -4,12 +4,12 @@ org.springframework spring-integration-tests jar - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE org.springframework spring-parent ../org.springframework.spring-parent - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE diff --git a/org.springframework.jdbc/pom.xml b/org.springframework.jdbc/pom.xml index d27a822aa82..9a7b1b3917d 100644 --- a/org.springframework.jdbc/pom.xml +++ b/org.springframework.jdbc/pom.xml @@ -4,12 +4,12 @@ org.springframework spring-jdbc jar - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE org.springframework spring-parent ../org.springframework.spring-parent - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE diff --git a/org.springframework.jms/pom.xml b/org.springframework.jms/pom.xml index 9a1c57ea5fb..fccb1e4be6d 100644 --- a/org.springframework.jms/pom.xml +++ b/org.springframework.jms/pom.xml @@ -4,12 +4,12 @@ org.springframework spring-jms jar - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE org.springframework spring-parent ../org.springframework.spring-parent - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE diff --git a/org.springframework.orm/pom.xml b/org.springframework.orm/pom.xml index 55b89c93189..b9afd4b7022 100644 --- a/org.springframework.orm/pom.xml +++ b/org.springframework.orm/pom.xml @@ -6,12 +6,12 @@ org.springframework spring-orm jar - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE org.springframework spring-parent ../org.springframework.spring-parent - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE diff --git a/org.springframework.oxm/pom.xml b/org.springframework.oxm/pom.xml index ffe6f8832dc..2217326212d 100644 --- a/org.springframework.oxm/pom.xml +++ b/org.springframework.oxm/pom.xml @@ -6,12 +6,12 @@ org.springframework spring-oxm jar - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE org.springframework spring-parent ../org.springframework.spring-parent - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE diff --git a/org.springframework.spring-library/pom.xml b/org.springframework.spring-library/pom.xml index 37e9857c3fa..67d84b46b7b 100644 --- a/org.springframework.spring-library/pom.xml +++ b/org.springframework.spring-library/pom.xml @@ -14,7 +14,7 @@ org.springframework spring-library libd - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE Spring Framework Spring is a layered Java/J2EE application platform, based on code published in Expert One-on-One J2EE Design and Development by Rod Johnson (Wrox, 2002). diff --git a/org.springframework.spring-parent/pom.xml b/org.springframework.spring-parent/pom.xml index 406689f7c2c..2d8a567c2f7 100644 --- a/org.springframework.spring-parent/pom.xml +++ b/org.springframework.spring-parent/pom.xml @@ -14,7 +14,7 @@ spring-parent pom Spring Framework - Parent - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE Spring Framework Parent https://fisheye.springframework.org/browse/spring-framework diff --git a/org.springframework.test/pom.xml b/org.springframework.test/pom.xml index 526c07ab442..628227cc639 100644 --- a/org.springframework.test/pom.xml +++ b/org.springframework.test/pom.xml @@ -4,12 +4,12 @@ org.springframework spring-test jar - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE org.springframework spring-parent ../org.springframework.spring-parent - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE diff --git a/org.springframework.transaction/pom.xml b/org.springframework.transaction/pom.xml index 1d5f7dfe896..a425a3d58ed 100644 --- a/org.springframework.transaction/pom.xml +++ b/org.springframework.transaction/pom.xml @@ -4,12 +4,12 @@ org.springframework spring-tx jar - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE org.springframework spring-parent ../org.springframework.spring-parent - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE diff --git a/org.springframework.web.portlet/pom.xml b/org.springframework.web.portlet/pom.xml index ac6678b3f4f..8375d335ceb 100644 --- a/org.springframework.web.portlet/pom.xml +++ b/org.springframework.web.portlet/pom.xml @@ -4,12 +4,12 @@ org.springframework spring-webmvc-portlet jar - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE org.springframework spring-parent ../org.springframework.spring-parent - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE diff --git a/org.springframework.web.servlet/pom.xml b/org.springframework.web.servlet/pom.xml index 8cba496d91b..5d73ea5fe0f 100644 --- a/org.springframework.web.servlet/pom.xml +++ b/org.springframework.web.servlet/pom.xml @@ -6,12 +6,12 @@ org.springframework spring-webmvc jar - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE org.springframework spring-parent ../org.springframework.spring-parent - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE diff --git a/org.springframework.web.struts/pom.xml b/org.springframework.web.struts/pom.xml index a82f148510e..ef83df0bf23 100644 --- a/org.springframework.web.struts/pom.xml +++ b/org.springframework.web.struts/pom.xml @@ -6,12 +6,12 @@ org.springframework spring-struts jar - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE org.springframework spring-parent ../org.springframework.spring-parent - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE diff --git a/org.springframework.web/pom.xml b/org.springframework.web/pom.xml index 1bf839f6489..40a18e0b6d6 100644 --- a/org.springframework.web/pom.xml +++ b/org.springframework.web/pom.xml @@ -5,12 +5,12 @@ org.springframework spring-web jar - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE org.springframework spring-parent ../org.springframework.spring-parent - 3.1.0.BUILD-SNAPSHOT + 3.1.0.RELEASE From abb5fc094a34eb094bdf90349cabb2115da40240 Mon Sep 17 00:00:00 2001 From: Chris Beams Date: Thu, 15 Dec 2011 02:28:49 +0100 Subject: [PATCH 02/22] Add spring-build 2.5.2 spring-build was previously included via an svn:external. Adding directly to the source tree under Git to avoid the need for a git submodule. In order to build from any earlier commit, it is recommended to export spring-build or symlink an existing copy into the root of the spring-framework project and then build normally. $ svn export https://src.springsource.org/svn/spring-build/tags/project-build-2.5.2 spring-build --- .gitignore | 1 - spring-build/aspect/artifact.xml | 33 + spring-build/aspect/common.xml | 45 ++ spring-build/aspect/default.xml | 25 + spring-build/aspect/package.xml | 22 + spring-build/aspect/publish.xml | 22 + spring-build/aspect/quality.xml | 74 ++ spring-build/common/artifact.xml | 120 ++++ spring-build/common/common.properties | 183 +++++ spring-build/common/common.xml | 240 +++++++ .../common/default-ivy-configurations.xml | 34 + spring-build/common/findbugs-exclude.xml | 22 + spring-build/common/ivysettings.xml | 82 +++ .../TableHeading-background.png | Bin 0 -> 2841 bytes spring-build/common/package.xml | 109 +++ spring-build/common/publish.xml | 110 +++ spring-build/common/quality.xml | 276 ++++++++ spring-build/common/spring-javadoc.css | 184 +++++ spring-build/docbook/common.xml | 21 + spring-build/docbook/css/html/highlight.css | 46 ++ spring-build/docbook/css/html/stylesheet.css | 75 ++ spring-build/docbook/default.xml | 24 + spring-build/docbook/documentation.xml | 182 +++++ spring-build/docbook/package.xml | 29 + spring-build/docbook/publish.xml | 44 ++ spring-build/docbook/styles/html/custom.xsl | 119 ++++ .../docbook/styles/html/titlepage.xml | 56 ++ spring-build/docbook/styles/pdf/custom.xsl | 661 ++++++++++++++++++ spring-build/docbook/styles/pdf/titlepage.xml | 96 +++ spring-build/lib/ivy/commons-codec.jar | Bin 0 -> 46725 bytes spring-build/lib/ivy/commons-httpclient.jar | Bin 0 -> 305001 bytes spring-build/lib/ivy/commons-logging.jar | Bin 0 -> 60686 bytes spring-build/lib/ivy/current.version | 20 + spring-build/lib/ivy/ivy.jar | Bin 0 -> 910990 bytes spring-build/lib/ivy/jets3t.jar | Bin 0 -> 355132 bytes spring-build/lib/ivy/jets3t.properties | 26 + .../ivy/org.springframework.build.aws.ivy.jar | Bin 0 -> 7446 bytes spring-build/library/artifact.xml | 52 ++ spring-build/library/common.xml | 21 + spring-build/library/default.xml | 25 + spring-build/library/package.xml | 37 + spring-build/library/publish.xml | 82 +++ spring-build/library/quality.xml | 35 + spring-build/multi-bundle/artifact.xml | 70 ++ spring-build/multi-bundle/common.xml | 120 ++++ spring-build/multi-bundle/default.xml | 25 + spring-build/multi-bundle/package.xml | 29 + spring-build/multi-bundle/publish.xml | 83 +++ spring-build/multi-bundle/quality.xml | 138 ++++ spring-build/par/artifact.xml | 66 ++ spring-build/par/common.xml | 21 + spring-build/par/default.xml | 25 + spring-build/par/package.xml | 31 + spring-build/par/publish.xml | 66 ++ spring-build/par/quality.xml | 22 + spring-build/resource/artifact.xml | 45 ++ spring-build/resource/common.xml | 21 + spring-build/resource/default.xml | 25 + spring-build/resource/package.xml | 39 ++ spring-build/resource/publish.xml | 82 +++ spring-build/resource/quality.xml | 35 + spring-build/standard/artifact.xml | 40 ++ spring-build/standard/common.xml | 48 ++ spring-build/standard/default.xml | 25 + spring-build/standard/package.xml | 22 + spring-build/standard/publish.xml | 22 + spring-build/standard/quality.xml | 22 + spring-build/war/artifact.xml | 85 +++ spring-build/war/common.xml | 48 ++ spring-build/war/default.xml | 25 + spring-build/war/package.xml | 31 + spring-build/war/publish.xml | 70 ++ spring-build/war/quality.xml | 74 ++ spring-build/weaving-external/artifact.xml | 83 +++ spring-build/weaving-external/common.xml | 48 ++ spring-build/weaving-external/default.xml | 25 + spring-build/weaving-external/package.xml | 22 + spring-build/weaving-external/publish.xml | 22 + spring-build/weaving-external/quality.xml | 63 ++ spring-build/weaving/artifact.xml | 59 ++ spring-build/weaving/common.xml | 50 ++ spring-build/weaving/default.xml | 25 + spring-build/weaving/package.xml | 22 + spring-build/weaving/publish.xml | 22 + spring-build/weaving/quality.xml | 45 ++ 85 files changed, 5173 insertions(+), 1 deletion(-) create mode 100644 spring-build/aspect/artifact.xml create mode 100644 spring-build/aspect/common.xml create mode 100644 spring-build/aspect/default.xml create mode 100644 spring-build/aspect/package.xml create mode 100644 spring-build/aspect/publish.xml create mode 100644 spring-build/aspect/quality.xml create mode 100644 spring-build/common/artifact.xml create mode 100644 spring-build/common/common.properties create mode 100644 spring-build/common/common.xml create mode 100644 spring-build/common/default-ivy-configurations.xml create mode 100644 spring-build/common/findbugs-exclude.xml create mode 100644 spring-build/common/ivysettings.xml create mode 100644 spring-build/common/javadoc-resources/TableHeading-background.png create mode 100644 spring-build/common/package.xml create mode 100644 spring-build/common/publish.xml create mode 100644 spring-build/common/quality.xml create mode 100644 spring-build/common/spring-javadoc.css create mode 100644 spring-build/docbook/common.xml create mode 100644 spring-build/docbook/css/html/highlight.css create mode 100644 spring-build/docbook/css/html/stylesheet.css create mode 100644 spring-build/docbook/default.xml create mode 100644 spring-build/docbook/documentation.xml create mode 100644 spring-build/docbook/package.xml create mode 100644 spring-build/docbook/publish.xml create mode 100644 spring-build/docbook/styles/html/custom.xsl create mode 100644 spring-build/docbook/styles/html/titlepage.xml create mode 100644 spring-build/docbook/styles/pdf/custom.xsl create mode 100644 spring-build/docbook/styles/pdf/titlepage.xml create mode 100644 spring-build/lib/ivy/commons-codec.jar create mode 100644 spring-build/lib/ivy/commons-httpclient.jar create mode 100644 spring-build/lib/ivy/commons-logging.jar create mode 100644 spring-build/lib/ivy/current.version create mode 100644 spring-build/lib/ivy/ivy.jar create mode 100644 spring-build/lib/ivy/jets3t.jar create mode 100644 spring-build/lib/ivy/jets3t.properties create mode 100644 spring-build/lib/ivy/org.springframework.build.aws.ivy.jar create mode 100644 spring-build/library/artifact.xml create mode 100644 spring-build/library/common.xml create mode 100644 spring-build/library/default.xml create mode 100644 spring-build/library/package.xml create mode 100644 spring-build/library/publish.xml create mode 100644 spring-build/library/quality.xml create mode 100644 spring-build/multi-bundle/artifact.xml create mode 100644 spring-build/multi-bundle/common.xml create mode 100644 spring-build/multi-bundle/default.xml create mode 100644 spring-build/multi-bundle/package.xml create mode 100644 spring-build/multi-bundle/publish.xml create mode 100644 spring-build/multi-bundle/quality.xml create mode 100644 spring-build/par/artifact.xml create mode 100644 spring-build/par/common.xml create mode 100644 spring-build/par/default.xml create mode 100644 spring-build/par/package.xml create mode 100644 spring-build/par/publish.xml create mode 100644 spring-build/par/quality.xml create mode 100644 spring-build/resource/artifact.xml create mode 100644 spring-build/resource/common.xml create mode 100644 spring-build/resource/default.xml create mode 100644 spring-build/resource/package.xml create mode 100644 spring-build/resource/publish.xml create mode 100644 spring-build/resource/quality.xml create mode 100644 spring-build/standard/artifact.xml create mode 100644 spring-build/standard/common.xml create mode 100644 spring-build/standard/default.xml create mode 100644 spring-build/standard/package.xml create mode 100644 spring-build/standard/publish.xml create mode 100644 spring-build/standard/quality.xml create mode 100644 spring-build/war/artifact.xml create mode 100644 spring-build/war/common.xml create mode 100644 spring-build/war/default.xml create mode 100644 spring-build/war/package.xml create mode 100644 spring-build/war/publish.xml create mode 100644 spring-build/war/quality.xml create mode 100644 spring-build/weaving-external/artifact.xml create mode 100644 spring-build/weaving-external/common.xml create mode 100644 spring-build/weaving-external/default.xml create mode 100644 spring-build/weaving-external/package.xml create mode 100644 spring-build/weaving-external/publish.xml create mode 100644 spring-build/weaving-external/quality.xml create mode 100644 spring-build/weaving/artifact.xml create mode 100644 spring-build/weaving/common.xml create mode 100644 spring-build/weaving/default.xml create mode 100644 spring-build/weaving/package.xml create mode 100644 spring-build/weaving/publish.xml create mode 100644 spring-build/weaving/quality.xml diff --git a/.gitignore b/.gitignore index f856d1d983c..b195d58b628 100644 --- a/.gitignore +++ b/.gitignore @@ -14,5 +14,4 @@ org.springframework.jdbc/derby.log org.springframework.spring-parent/.classpath org.springframework.spring-parent/.project org.springframework.test/test-output/ -spring-build target diff --git a/spring-build/aspect/artifact.xml b/spring-build/aspect/artifact.xml new file mode 100644 index 00000000000..ec467be26b0 --- /dev/null +++ b/spring-build/aspect/artifact.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-build/aspect/common.xml b/spring-build/aspect/common.xml new file mode 100644 index 00000000000..48a15242ceb --- /dev/null +++ b/spring-build/aspect/common.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-build/aspect/default.xml b/spring-build/aspect/default.xml new file mode 100644 index 00000000000..98907595da7 --- /dev/null +++ b/spring-build/aspect/default.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/spring-build/aspect/package.xml b/spring-build/aspect/package.xml new file mode 100644 index 00000000000..49763b223e0 --- /dev/null +++ b/spring-build/aspect/package.xml @@ -0,0 +1,22 @@ + + + + + + + + \ No newline at end of file diff --git a/spring-build/aspect/publish.xml b/spring-build/aspect/publish.xml new file mode 100644 index 00000000000..a3ce58ac703 --- /dev/null +++ b/spring-build/aspect/publish.xml @@ -0,0 +1,22 @@ + + + + + + + + \ No newline at end of file diff --git a/spring-build/aspect/quality.xml b/spring-build/aspect/quality.xml new file mode 100644 index 00000000000..3af890844d2 --- /dev/null +++ b/spring-build/aspect/quality.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-build/common/artifact.xml b/spring-build/common/artifact.xml new file mode 100644 index 00000000000..bf00a872a30 --- /dev/null +++ b/spring-build/common/artifact.xml @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-build/common/common.properties b/spring-build/common/common.properties new file mode 100644 index 00000000000..f8aaea0e537 --- /dev/null +++ b/spring-build/common/common.properties @@ -0,0 +1,183 @@ +# Copyright 2010 SpringSource +# +# 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. + +# Common Properties +lib.dir=${spring.build.dir}/lib +artifacts.dir=${target.dir}/artifacts +target.dir=${basedir}/target +ci.build=false +natural.name=${ant.project.name} +build.stamp=BUILD-${timestamp} +bundle.version=${version}.${build.stamp} +publish.bucket=repository.springsource.com +local.repo.dir=${java.io.tmpdir}/local-repository + +# Artifact Properties +license.dir=${basedir} +main.java.dir=${basedir}/src/main/java +main.resources.dir=${basedir}/src/main/resources +main.output.dir=${target.dir}/classes +main.webapp.dir=${basedir}/src/main/webapp + +# Javadoc Properties +javadoc-all.output.dir=${target.dir}/javadoc-all +javadoc-api.output.dir=${target.dir}/javadoc-api +javadoc.prep.dir=${target.dir}/javadoc-prep +javadoc.exclude.package.names= +javadoc.stylesheet.file=${spring.build.dir}/common/spring-javadoc.css +javadoc.resources.dir=${spring.build.dir}/common/javadoc-resources +javadoc.max.memory=128M + +# JAR Properties +implementation.title=${ant.project.name} +implementation.version=${bundle.version} +jar.output.dir=${artifacts.dir} +jar.output.file=${jar.output.dir}/${ant.project.name}.jar +source-jar.output.dir=${artifacts.dir} +source-jar.output.file=${source-jar.output.dir}/${ant.project.name}-sources.jar + +# PAR Properties +par.output.dir=${artifacts.dir} +par.output.file=${par.output.dir}/${ant.project.name}.par +par.provided.dir=${target.dir}/par-provided +par.provided.bundles.dir=${par.provided.dir}/bundles +par.provided.libraries.dir=${par.provided.dir}/libraries +par.staging.dir=${target.dir}/par-expanded +application.name= +application.description= + +# Web Module Properties +web.module.output.dir=${artifacts.dir} +web.module.output.file=${web.module.output.dir}/${ant.project.name}.jar +web.module.staging.dir=${target.dir}/web-module-expanded +web.module.classes.dir=${web.module.staging.dir}/WEB-INF/classes + +# Library Properties +libd.input.file=${basedir}/${ant.project.name}.libd +libd.output.dir=${artifacts.dir} +libd.output.file=${libd.output.dir}/${ant.project.name}.libd + +# Resource Properties +resource.src.dir=${basedir}/src + +# WAR Properties +war.output.dir=${artifacts.dir} +war.output.file=${war.output.dir}/${ant.project.name}.war +war.staging.dir=${target.dir}/war-expanded +war.classes.dir=${war.staging.dir}/WEB-INF/classes +war.lib.dir=${war.staging.dir}/WEB-INF/lib + +# Compiler Properties +org.springframework.build.ant.version=1.1.0.RELEASE +org.eclipse.jdt.core.compiler.batch.version=3.3.0 +build.compiler=org.eclipse.jdt.core.JDTCompilerAdapter +compile.debug=true +compile.debug.level=lines,vars,source +compiler.args=-enableJavadoc +source.version=1.5 +target.version=${source.version} + +# Package Properties +copy.to.dir=${package.dist.dir} +package.dir=${target.dir}/package-expanded +package.basename=${natural.name}-${bundle.version} +package.file.name=${package.basename}.zip +package.output.dir=${package.dir}/${package.basename} +package.output.file=${artifacts.dir}/${package.file.name} +package.dist.dir=${package.output.dir}/dist +package.lib.dir=${package.output.dir}/lib +package.src.dir=${package.output.dir}/src +package.docs.dir=${package.output.dir}/docs +package.jar.output.file=${ant.project.name}-${bundle.version}.jar +package.par.output.file=${ant.project.name}-${bundle.version}.par +package.libd.output.file=${ant.project.name}-${bundle.version}.libd +package.war.output.file=${ant.project.name}-${bundle.version}.war +package.source-jar.output.file=${ant.project.name}-sources-${bundle.version}.jar +org.springframework.build.aws.ant.version=3.0.3.RELEASE + +# AspectJ Properties +org.aspectj.tools.version=1.6.8.RELEASE +aspectj.x= + +# Test Properties +test.forkmode=perBatch +test.java.dir=${basedir}/src/test/java +test.resources.dir=${basedir}/src/test/resources +test.output.dir=${target.dir}/test-classes +test-results.output.dir=${target.dir}/test-results +test.vm.args= + +# Clover Properties +clover.db.dir=${clover.output.dir}/db +clover.db.file=${clover.db.dir}/clover.db +clover.output.dir=${target.dir}/clover +clover.staging.dir=${clover.output.dir}/staging +main.clover.dir=${clover.staging.dir}/main +test.clover.dir=${clover.staging.dir}/test +com.springsource.com.cenqua.clover.version=2.6.0 +clover.enforce=false +clover.coverage=0% + +# Docbook Properties +docbook.dir=${lib.dir}/docbook +docbook.target.dir=${target.dir}/docbook +org.apache.velocity.docbookframework.dist.version=1.0.0.BUILD-20080625 +com.springsource.net.sf.xslthl.version=1.2.0 +com.springsource.org.apache.xerces.version=2.8.1 +docbook.build.dir=${spring.build.dir}/docbook +docbook.output.dir=${target.dir}/${ant.project.name} +docbook.staging.dir=${docbook.target.dir}/staging +docbook.src.dir=${basedir}/src +docbook.images.dir=${basedir}/images +docbook.css.dir=${basedir}/css +docbook.styles.dir=${basedir}/styles + +# Findbugs Properties +findbugs.dir=${lib.dir}/findbugs +findbugs.exclude.file=${spring.build.dir}/common/findbugs-exclude.xml +findbugs.output.dir=${target.dir}/findbugs +findbugs.output.file=${findbugs.output.dir}/${ant.project.name}.xml +edu.umd.cs.findbugs.version=1.3.7 + +# Ivy Properties +bucket.basename=springframework.org +release.type=integration +ivy.checksums=sha1 +ivy.deliver.revision=${bundle.version} +ivy.file=${basedir}/ivy.xml +ivy.lib.dir=${lib.dir}/ivy +ivy.output.dir=${artifacts.dir} +ivy.output.file=${ivy.output.dir}/ivy.xml +ivy.settings.file=${spring.build.dir}/common/ivysettings.xml + +# Maven Properties +pom.output.dir=${artifacts.dir} +pom.output.file=${pom.output.dir}/pom.xml +local.pom.output.file=${basedir}/pom.xml +org.apache.maven.ant.version=2.0.10 +org.springframework.build.aws.maven.version=2.0.0.RELEASE + +# Bundlor Properties +bundlor.ant.version=1.0.0.RELEASE +manifest.template.file=${basedir}/template.mf +merge.existing.headers=true +fail.on.warnings=true + +# OSGi Properties +org.springframework.build.osgi.version=1.0.0.RELEASE +org.eclipse.osgi.version=3.5.0.v20090311-1300 + +#S3 Properties +accessKey= +secretKey= diff --git a/spring-build/common/common.xml b/spring-build/common/common.xml new file mode 100644 index 00000000000..4973529acb6 --- /dev/null +++ b/spring-build/common/common.xml @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
]]>
+
+ + + +
+
+ + + + + +
\ No newline at end of file diff --git a/spring-build/common/default-ivy-configurations.xml b/spring-build/common/default-ivy-configurations.xml new file mode 100644 index 00000000000..a8658ff7952 --- /dev/null +++ b/spring-build/common/default-ivy-configurations.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/spring-build/common/findbugs-exclude.xml b/spring-build/common/findbugs-exclude.xml new file mode 100644 index 00000000000..3d9127e5807 --- /dev/null +++ b/spring-build/common/findbugs-exclude.xml @@ -0,0 +1,22 @@ + + + + + + + + diff --git a/spring-build/common/ivysettings.xml b/spring-build/common/ivysettings.xml new file mode 100644 index 00000000000..587842a9709 --- /dev/null +++ b/spring-build/common/ivysettings.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spring-build/common/javadoc-resources/TableHeading-background.png b/spring-build/common/javadoc-resources/TableHeading-background.png new file mode 100644 index 0000000000000000000000000000000000000000..72d65e771f0dd4ab8840ca15ab9eec9c9e664957 GIT binary patch literal 2841 zcmV+!3+D8RP)KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z0000)Nkl&$u(bq3jF1*G;sr1OFqAOfkahT?00000NkvXXu0mjf^-)D& literal 0 HcmV?d00001 diff --git a/spring-build/common/package.xml b/spring-build/common/package.xml new file mode 100644 index 00000000000..b83a431a360 --- /dev/null +++ b/spring-build/common/package.xml @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-build/common/publish.xml b/spring-build/common/publish.xml new file mode 100644 index 00000000000..5fcff6a091d --- /dev/null +++ b/spring-build/common/publish.xml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-build/common/quality.xml b/spring-build/common/quality.xml new file mode 100644 index 00000000000..0dba1e5e7b4 --- /dev/null +++ b/spring-build/common/quality.xml @@ -0,0 +1,276 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-build/common/spring-javadoc.css b/spring-build/common/spring-javadoc.css new file mode 100644 index 00000000000..191be29d144 --- /dev/null +++ b/spring-build/common/spring-javadoc.css @@ -0,0 +1,184 @@ +/* + * Copyright 2010 SpringSource + * + * 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. + */ + +.code +{ + border: 1px solid black; + background-color: #F4F4F4; + padding: 5px; +} + +body +{ + font: 12px Verdana, Arial, Helvetica, "Bitstream Vera Sans", sans-serif; + background-color: #fff; + color: #333; +} + + +/* Link colors */ +a +{ + color:#2c7b14; + text-decoration:none; +} + +a:hover +{ + text-decoration:underline; +} + +/* Headings */ +h1 +{ + font-size:28px; + color:#007c00; +} + +/* Table colors */ + +table +{ + border:none; +} + +td +{ + border:none; + border-bottom:1px dotted #ddd; +} + +th +{ + border:none; +} + +.TableHeadingColor th +{ + background-color: #efffcb; + background-image: url(resources/TableHeading-background.png); + background-repeat: repeat-x; + color:#fff; + font-size:14px; + height:26px; +} + +.TableSubHeadingColor +{ + background: #f7ffee; + +} +.TableRowColor +{ + background: #fff; +} + +.TableRowColor a +{ + border-bottom:none; + color:#2c7b14; + font-weight:normal; +} + +tr.TableRowColor:hover +{ + background:#eef2e1; +} + + +/* Font used in left-hand frame lists */ +.FrameTitleFont +{ + font-size: 120%; + font-weight:bold; +} + +.FrameTitleFont a +{ + color: #333; +} + +.FrameHeadingFont +{ + font-weight: bold; + font-size:95%; +} + +.FrameItemFont +{ + line-height:130%; + font-size: 95%; +} + +.FrameItemFont a +{ + color:#333; +} + +.FrameItemFont a:hover +{ + color:#249901; + border-bottom:none; + text-decoration:underline; +} + +/* Navigation bar fonts and colors */ +.NavBarCell1 +{ + background-color:#fff; + border:none; +} + +.NavBarCell1Rev +{ + background-color:#e3faa5; + border:1px solid #9ad00c; + padding:0; + margin:0; +} + +.NavBarCell1 a +{ + color:#333; + text-decoration:none; +} + +.NavBarFont1Rev +{ + +} + +.NavBarCell2 +{ + border:none; +} + +.NavBarCell2 a +{ + color:#249901; + font-size:90%; +} + +.NavBarCell3 +{ + border:none; +} + +/* Override sizes in font tags */ +font +{ + font: inherit !important; +} diff --git a/spring-build/docbook/common.xml b/spring-build/docbook/common.xml new file mode 100644 index 00000000000..21d2958443a --- /dev/null +++ b/spring-build/docbook/common.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/spring-build/docbook/css/html/highlight.css b/spring-build/docbook/css/html/highlight.css new file mode 100644 index 00000000000..35104afc4ea --- /dev/null +++ b/spring-build/docbook/css/html/highlight.css @@ -0,0 +1,46 @@ +/* + * Copyright 2010 SpringSource + * + * 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. + */ + +.hl-keyword { + color: #7F0055; + font-weight: bold; +} + +.hl-comment { + color: #3F5F5F; + font-style: italic; +} + +.hl-multiline-comment { + color: #3F5FBF; + font-style: italic; +} + +.hl-tag { + color: #3F7F7F; +} + +.hl-attribute { + color: #7F007F; +} + +.hl-value { + color: #2A00FF; +} + +.hl-string { + color: #2A00FF; +} \ No newline at end of file diff --git a/spring-build/docbook/css/html/stylesheet.css b/spring-build/docbook/css/html/stylesheet.css new file mode 100644 index 00000000000..39491bf3b74 --- /dev/null +++ b/spring-build/docbook/css/html/stylesheet.css @@ -0,0 +1,75 @@ +/* + * Copyright 2010 SpringSource + * + * 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. + */ + +@IMPORT url("highlight.css"); + +html { + padding: 0pt; + margin: 0pt; +} + +body { + margin-left: 10%; + margin-right: 10%; + font-family: Arial, Sans-serif; +} + +div { + margin: 0pt; +} + +p { + text-align: justify; +} + +hr { + border: 1px solid gray; + background: gray; +} + +h1,h2,h3,h4 { + color: #234623; + font-family: Arial, Sans-serif; +} + +pre { + line-height: 1.0; + color: black; +} + +pre.programlisting { + font-size: 10pt; + padding: 7pt 3pt; + border: 1pt solid black; + background: #eeeeee; + clear: both; +} + +div.table { + margin: 1em; + padding: 0.5em; + text-align: center; +} + +div.table table { + display: table; + width: 100%; +} + +div.table td { + padding-left: 7px; + padding-right: 7px; +} diff --git a/spring-build/docbook/default.xml b/spring-build/docbook/default.xml new file mode 100644 index 00000000000..50ab46a3aee --- /dev/null +++ b/spring-build/docbook/default.xml @@ -0,0 +1,24 @@ + + + + + + + + + + \ No newline at end of file diff --git a/spring-build/docbook/documentation.xml b/spring-build/docbook/documentation.xml new file mode 100644 index 00000000000..e51651b113b --- /dev/null +++ b/spring-build/docbook/documentation.xml @@ -0,0 +1,182 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-build/docbook/package.xml b/spring-build/docbook/package.xml new file mode 100644 index 00000000000..b66bfad5ff4 --- /dev/null +++ b/spring-build/docbook/package.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-build/docbook/publish.xml b/spring-build/docbook/publish.xml new file mode 100644 index 00000000000..d572e1461e3 --- /dev/null +++ b/spring-build/docbook/publish.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-build/docbook/styles/html/custom.xsl b/spring-build/docbook/styles/html/custom.xsl new file mode 100644 index 00000000000..9e67ce90d38 --- /dev/null +++ b/spring-build/docbook/styles/html/custom.xsl @@ -0,0 +1,119 @@ + + + + + + 1 + 0 + 1 + + + + images/ + .gif + + 120 + images/callouts/ + .gif + + + css/stylesheet.css + text/css + book toc,title + + text-align: left + + + + + + + + + + + + + + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Begin Google Analytics code + + + End Google Analytics code + + + \ No newline at end of file diff --git a/spring-build/docbook/styles/html/titlepage.xml b/spring-build/docbook/styles/html/titlepage.xml new file mode 100644 index 00000000000..3e4f90b47b0 --- /dev/null +++ b/spring-build/docbook/styles/html/titlepage.xml @@ -0,0 +1,56 @@ + + + + + + + + + + <subtitle/> + <corpauthor/> + <authorgroup/> + <author/> + <mediaobject/> + <othercredit/> + <productname/> + <releaseinfo/> + <copyright/> + <pubdate/> + <revision/> + <revhistory/> + <abstract/> + </t:titlepage-content> + + <t:titlepage-content t:side="verso"> + <legalnotice/> + </t:titlepage-content> + + <t:titlepage-separator> + <hr/> + </t:titlepage-separator> + + <t:titlepage-before t:side="recto"> + </t:titlepage-before> + + <t:titlepage-before t:side="verso"> + </t:titlepage-before> +</t:titlepage> + +</t:templates> diff --git a/spring-build/docbook/styles/pdf/custom.xsl b/spring-build/docbook/styles/pdf/custom.xsl new file mode 100644 index 00000000000..587ee408682 --- /dev/null +++ b/spring-build/docbook/styles/pdf/custom.xsl @@ -0,0 +1,661 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + xmlns:fo="http://www.w3.org/1999/XSL/Format" + xmlns:xslthl="http://xslthl.sf.net" + exclude-result-prefixes="xslthl" + version='1.0'> + + <!-- Use nice graphics for admonitions --> + <xsl:param name="admon.graphics">'1'</xsl:param> + <xsl:param name="admon.graphics.path">@file.prefix@@dbf.xsl@/images/</xsl:param> + + <xsl:param name="draft.watermark.image" select="'@file.prefix@@dbf.xsl@/images/draft.png'"/> + <xsl:param name="paper.type" select="'@paper.type@'"/> + + <xsl:param name="page.margin.top" select="'1cm'"/> + <xsl:param name="region.before.extent" select="'1cm'"/> + <xsl:param name="body.margin.top" select="'1.5cm'"/> + + <xsl:param name="body.margin.bottom" select="'1.5cm'"/> + <xsl:param name="region.after.extent" select="'1cm'"/> + <xsl:param name="page.margin.bottom" select="'1cm'"/> + <xsl:param name="title.margin.left" select="'0cm'"/> + + <!-- Leave image paths as relative when navigating XInclude --> + <xsl:param name="keep.relative.image.uris" select="1"/> + +<!--################################################### + Header and Footer control + ################################################### --> + + <!-- Number of levels of sections to include in markers (for running headings/footings). Default is 2. --> + <xsl:param name="marker.section.level">1</xsl:param> + + <!-- Remove rules from top and bottom of the page --> + <xsl:param name="header.rule" select="0"></xsl:param> + <xsl:param name="footer.rule" select="0"></xsl:param> + +<!-- More space in the center header for long text + <xsl:attribute-set name="header.content.properties"> + <xsl:attribute name="font-family"> + <xsl:value-of select="$body.font.family"/> + </xsl:attribute> + <xsl:attribute name="margin-left">-5em</xsl:attribute> + <xsl:attribute name="margin-right">-5em</xsl:attribute> + </xsl:attribute-set> +--> +<!--################################################### + Table of Contents + ################################################### --> + + <xsl:param name="generate.toc"> + book toc,title + </xsl:param> + + <!-- Show only Sections up to level 1 in the TOCs --> + <xsl:param name="toc.section.depth">1</xsl:param> + +<!--################################################### + Custom Header and Footer + ################################################### --> +<!-- + pageclass + + There is a specific pageclass value for each type of page design that might be needed. For example, an index might + be two-column layout while the rest of the book is single column. Each pageclass has a set of FO simple-page-masters + defined for it. The following pageclass values are available by default, but this list could be extended by adding + custom page masters. + + titlepage Division title page, including set, book, part. + lot Page with a list of titles, including book table of contents, list of figures, etc. + front Front matter pages, including preface, dedication + body Main content pages + back Back matter pages, including appendix, glossary, etc. + index Alphabetical book-style index + + sequence + + Within a pageclass, the sequence of pages can have different page designs. For example, the first page of sequence + might omit the running header so it will not detract from the main title. The enumerated sequence values are: + + first First page of a page class. + odd Odd-numbered pages in the page class. + even Even-numbered pages. + blank Blank page at end of sequence, to even out page count. + + If the output format is single-sided, then odd and even pages should have the same design, and the blank page is + not called upon. +--> + <xsl:template name="header.content"> + <xsl:param name="pageclass" select="''"/> + <xsl:param name="sequence" select="''"/> + <xsl:param name="position" select="''"/> + <xsl:param name="gentext-key" select="''"/> + + <xsl:variable name="ProductName"> + <xsl:choose> + <xsl:when test="//productname"> + <xsl:value-of select="//productname"/><xsl:text> </xsl:text> + </xsl:when> + <xsl:otherwise> + <xsl:text>please define productname in your docbook file!</xsl:text> + </xsl:otherwise> + </xsl:choose> + </xsl:variable> + + <xsl:variable name="TitleAbbrev"> + <xsl:choose> + <xsl:when test="//titleabbrev"> + <xsl:value-of select="//titleabbrev"/><xsl:text> </xsl:text> + </xsl:when> + <xsl:otherwise> + <xsl:text>please define titleabbrev in your docbook file!</xsl:text> + </xsl:otherwise> + </xsl:choose> + </xsl:variable> + + <!-- $double.sided can be 0 or 1, meaning false or true respectively --> + <!-- pageclass can be titlepage, lot, front, body, back, index --> + <!-- sequence can be first, odd, even, blank --> + <!-- position can be left, center, right --> + <xsl:choose> + <xsl:when test="$double.sided != 0"> + <xsl:choose> + <xsl:when test="$pageclass='titlepage'"><!-- nop --></xsl:when> + <xsl:when test="$pageclass='lot'"> <!-- nop --></xsl:when> + + <xsl:when test="$pageclass='front' or $pageclass='body'"> + <xsl:choose> + <xsl:when test="$sequence='first' or $sequence='odd'"> + <xsl:choose> + <xsl:when test="$position='left'"> + <xsl:apply-templates select="." mode="titleabbrev.markup"/> <!-- chapter header --> + </xsl:when> + <xsl:when test="$position='center'"> + <!-- + <xsl:value-of select="$TitleAbbrev"/> + --> + </xsl:when> + <xsl:when test="$position='right'"> + <fo:page-number/> + </xsl:when> + </xsl:choose> + </xsl:when> + + <xsl:when test="$sequence='even' or $sequence='blank'"> + <xsl:choose> + <xsl:when test="$position='left'"> + <fo:page-number/> + </xsl:when> + <xsl:when test="$position='center'"> + <!-- + <fo:retrieve-marker retrieve-class-name="section.head.marker" + retrieve-position="first-including-carryover" + retrieve-boundary="page-sequence"/> + --> + </xsl:when> + <xsl:when test="$position='right'"> + <xsl:value-of select="$TitleAbbrev"/> + </xsl:when> + </xsl:choose> + </xsl:when> + </xsl:choose> + </xsl:when> + + <xsl:when test="$pageclass='back'"> <!-- nop --></xsl:when> + <xsl:when test="$pageclass='index'"> <!-- nop --></xsl:when> + <xsl:otherwise> <!-- nop --></xsl:otherwise> + </xsl:choose> + </xsl:when> + <xsl:when test="$double.sided = 0"> + <xsl:choose> + <xsl:when test="$pageclass='titlepage'"><!-- nop --></xsl:when> + <xsl:when test="$pageclass='lot'"> <!-- nop --></xsl:when> + + <xsl:when test="$pageclass='front' or $pageclass='body'"> + <xsl:choose> + <xsl:when test="$sequence='first' or $sequence='odd' or $sequence='even' or $sequence='blank'"> + <xsl:choose> + <xsl:when test="$position='left'"> + <xsl:apply-templates select="." mode="titleabbrev.markup"/> <!-- chapter header --> + </xsl:when> + <xsl:when test="$position='center'"> + <!-- + <xsl:value-of select="$TitleAbbrev"/> + --> + </xsl:when> + <xsl:when test="$position='right'"> + <fo:page-number/> + </xsl:when> + </xsl:choose> + </xsl:when> + </xsl:choose> + </xsl:when> + + <xsl:when test="$pageclass='back'"> <!-- nop --></xsl:when> + <xsl:when test="$pageclass='index'"> <!-- nop --></xsl:when> + <xsl:otherwise> <!-- nop --></xsl:otherwise> + </xsl:choose> + </xsl:when> + </xsl:choose> + + + </xsl:template> + +<!--################################################### + Custom Footer + ################################################### --> + + <xsl:template name="footer.content"> + <xsl:param name="pageclass" select="''"/> + <xsl:param name="sequence" select="''"/> + <xsl:param name="position" select="''"/> + <xsl:param name="gentext-key" select="''"/> + + <xsl:variable name="Version"> + <xsl:choose> + <xsl:when test="//releaseinfo"> + <xsl:value-of select="//releaseinfo"/> + </xsl:when> + <xsl:otherwise> + <!-- nop --> + </xsl:otherwise> + </xsl:choose> + </xsl:variable> + + <xsl:variable name="TitleAbbrev"> + <xsl:choose> + <xsl:when test="//titleabbrev"> + <xsl:value-of select="//titleabbrev"/><xsl:text> </xsl:text> + </xsl:when> + <xsl:otherwise> + <xsl:text>please define titleabbrev in your docbook file!</xsl:text> + </xsl:otherwise> + </xsl:choose> + </xsl:variable> + + <!-- $double.sided can be 0 or 1, meaning false or true respectively --> + <!-- pageclass can be titlepage, lot, front, body, back, index --> + <!-- sequence can be first, odd, even, blank --> + <!-- position can be left, center, right --> + <xsl:choose> + <xsl:when test="$double.sided != 0"> + <xsl:choose> + <xsl:when test="$pageclass='titlepage'"> <!-- nop --></xsl:when> + + <xsl:when test="$pageclass='lot' or $pageclass='front' or $pageclass='body'"> + <xsl:choose> + <xsl:when test="$pageclass!='titlepage' and ($sequence='first' or $sequence='odd')"> + <xsl:choose> + <xsl:when test="$position='left'"> + <xsl:value-of select="$Version"/> + </xsl:when> + <xsl:when test="$position='center'"> + <!-- + <xsl:value-of select="$TitleAbbrev"/> + <fo:retrieve-marker retrieve-class-name="section.head.marker" + retrieve-position="first-including-carryover" + retrieve-boundary="page-sequence"/> + --> + </xsl:when> + <xsl:when test="$position='right'"> + <fo:page-number/> + </xsl:when> + </xsl:choose> + </xsl:when> + + <xsl:when test="$sequence='even' or $sequence='blank'"> + <xsl:choose> + <xsl:when test="$position='left'"> + <fo:page-number/> + </xsl:when> + <xsl:when test="$position='center'"> + <!-- + <xsl:value-of select="$TitleAbbrev"/> + --> + </xsl:when> + <xsl:when test="$position='right'"> + <xsl:apply-templates select="." mode="titleabbrev.markup"/> <!-- chapter header --> + </xsl:when> + </xsl:choose> + </xsl:when> + </xsl:choose> + </xsl:when> + + <xsl:when test="$pageclass='back'"> <!-- nop --></xsl:when> + <xsl:when test="$pageclass='index'"> <!-- nop --></xsl:when> + <xsl:otherwise> <!-- nop --></xsl:otherwise> + </xsl:choose> + </xsl:when> + <xsl:when test="$double.sided = 0"> + <xsl:choose> + <xsl:when test="$pageclass='titlepage'"><!-- nop --></xsl:when> + <xsl:when test="$pageclass='lot'"> <!-- nop --></xsl:when> + + <xsl:when test="$pageclass='front' or $pageclass='body'"> + <xsl:choose> + <xsl:when test="$sequence='first' or $sequence='odd' or $sequence='even' or $sequence='blank'"> + <xsl:choose> + <xsl:when test="$position='left'"> + <xsl:value-of select="$Version"/> + </xsl:when> + <xsl:when test="$position='center'"> + <fo:retrieve-marker retrieve-class-name="section.head.marker" + retrieve-position="first-including-carryover" + retrieve-boundary="page-sequence"/> + </xsl:when> + <xsl:when test="$position='right'"> + <fo:page-number/> + </xsl:when> + </xsl:choose> + </xsl:when> + </xsl:choose> + </xsl:when> + + <xsl:when test="$pageclass='back'"> <!-- nop --></xsl:when> + <xsl:when test="$pageclass='index'"> <!-- nop --></xsl:when> + <xsl:otherwise> <!-- nop --></xsl:otherwise> + </xsl:choose> + </xsl:when> + </xsl:choose> + + </xsl:template> + + <xsl:template match="processing-instruction('hard-pagebreak')"> + <fo:block break-before='page'/> + </xsl:template> + +<!--################################################### + Extensions + ################################################### --> + +<!-- These extensions are required for table printing and other stuff --> + <xsl:param name="use.extensions">1</xsl:param> + <xsl:param name="tablecolumns.extension">0</xsl:param> + <xsl:param name="callout.extensions">1</xsl:param> + <xsl:param name="fop.extensions">1</xsl:param> + +<!--################################################### + Paper & Page Size + ################################################### --> + +<!-- Paper type, no headers on blank pages, no double sided printing --> + <xsl:param name="double.sided">1</xsl:param> + <xsl:param name="headers.on.blank.pages">1</xsl:param> + <xsl:param name="footers.on.blank.pages">1</xsl:param> + +<!--################################################### + Fonts & Styles + ################################################### --> + <xsl:param name="alignment">left</xsl:param> + + <xsl:param name="hyphenate">false</xsl:param> + + <xsl:attribute-set name="footer.content.properties"> + <xsl:attribute name="font-family"> + <xsl:value-of select="$body.fontset"/> + </xsl:attribute> + </xsl:attribute-set> + +<!-- Default Font size --> + <xsl:param name="body.font.master">12</xsl:param> + <xsl:param name="body.font.small">8</xsl:param> + +<!-- Line height in body text --> + <xsl:param name="line-height">1.2</xsl:param> + +<!-- Chapter title size --> + <xsl:attribute-set name="chapter.titlepage.recto.style"> + <xsl:attribute name="text-align">left</xsl:attribute> + <xsl:attribute name="font-weight">bold</xsl:attribute> + <xsl:attribute name="font-size"> + <xsl:value-of select="$body.font.master * 1.8"/> + <xsl:text>pt</xsl:text> + </xsl:attribute> + </xsl:attribute-set> + +<!-- Why is the font-size for chapters hardcoded in the XSL FO templates? + Let's remove it, so this sucker can use our attribute-set only... --> + <xsl:template match="title" mode="chapter.titlepage.recto.auto.mode"> + <fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" + xsl:use-attribute-sets="chapter.titlepage.recto.style"> + <xsl:call-template name="component.title"> + <xsl:with-param name="node" select="ancestor-or-self::chapter[1]"/> + </xsl:call-template> + </fo:block> + </xsl:template> + +<!-- Sections 1, 2 and 3 titles have a small bump factor and padding --> + <xsl:attribute-set name="section.title.level1.properties"> + <xsl:attribute name="space-before.optimum">0.8em</xsl:attribute> + <xsl:attribute name="space-before.minimum">0.8em</xsl:attribute> + <xsl:attribute name="space-before.maximum">0.8em</xsl:attribute> + <xsl:attribute name="font-size"> + <xsl:value-of select="$body.font.master * 1.5"/> + <xsl:text>pt</xsl:text> + </xsl:attribute> + <xsl:attribute name="space-after.optimum">0.1em</xsl:attribute> + <xsl:attribute name="space-after.minimum">0.1em</xsl:attribute> + <xsl:attribute name="space-after.maximum">0.1em</xsl:attribute> + </xsl:attribute-set> + <xsl:attribute-set name="section.title.level2.properties"> + <xsl:attribute name="space-before.optimum">0.6em</xsl:attribute> + <xsl:attribute name="space-before.minimum">0.6em</xsl:attribute> + <xsl:attribute name="space-before.maximum">0.6em</xsl:attribute> + <xsl:attribute name="font-size"> + <xsl:value-of select="$body.font.master * 1.25"/> + <xsl:text>pt</xsl:text> + </xsl:attribute> + <xsl:attribute name="space-after.optimum">0.1em</xsl:attribute> + <xsl:attribute name="space-after.minimum">0.1em</xsl:attribute> + <xsl:attribute name="space-after.maximum">0.1em</xsl:attribute> + </xsl:attribute-set> + <xsl:attribute-set name="section.title.level3.properties"> + <xsl:attribute name="space-before.optimum">0.4em</xsl:attribute> + <xsl:attribute name="space-before.minimum">0.4em</xsl:attribute> + <xsl:attribute name="space-before.maximum">0.4em</xsl:attribute> + <xsl:attribute name="font-size"> + <xsl:value-of select="$body.font.master * 1.0"/> + <xsl:text>pt</xsl:text> + </xsl:attribute> + <xsl:attribute name="space-after.optimum">0.1em</xsl:attribute> + <xsl:attribute name="space-after.minimum">0.1em</xsl:attribute> + <xsl:attribute name="space-after.maximum">0.1em</xsl:attribute> + </xsl:attribute-set> + +<!-- Use code syntax highlighting --> + <xsl:param name="highlight.source" select="1"/> + <xsl:param name="highlight.default.language" select="xml" /> + + <xsl:template match='xslthl:keyword'> + <fo:inline font-weight="bold" color="#7F0055"><xsl:apply-templates/></fo:inline> + </xsl:template> + + <xsl:template match='xslthl:comment'> + <fo:inline font-style="italic" color="#3F5F5F"><xsl:apply-templates/></fo:inline> + </xsl:template> + + <xsl:template match='xslthl:oneline-comment'> + <fo:inline font-style="italic" color="#3F5F5F"><xsl:apply-templates/></fo:inline> + </xsl:template> + + <xsl:template match='xslthl:multiline-comment'> + <fo:inline font-style="italic" color="#3F5FBF"><xsl:apply-templates/></fo:inline> + </xsl:template> + + <xsl:template match='xslthl:tag'> + <fo:inline color="#3F7F7F"><xsl:apply-templates/></fo:inline> + </xsl:template> + + <xsl:template match='xslthl:attribute'> + <fo:inline color="#7F007F"><xsl:apply-templates/></fo:inline> + </xsl:template> + + <xsl:template match='xslthl:value'> + <fo:inline color="#2A00FF"><xsl:apply-templates/></fo:inline> + </xsl:template> + + <xsl:template match='xslthl:string'> + <fo:inline color="#2A00FF"><xsl:apply-templates/></fo:inline> + </xsl:template> + +<!--################################################### + Tables + ################################################### --> + + <!-- Some padding inside tables --> + <xsl:attribute-set name="table.cell.padding"> + <xsl:attribute name="padding-left">4pt</xsl:attribute> + <xsl:attribute name="padding-right">4pt</xsl:attribute> + <xsl:attribute name="padding-top">4pt</xsl:attribute> + <xsl:attribute name="padding-bottom">4pt</xsl:attribute> + </xsl:attribute-set> + +<!-- Only hairlines as frame and cell borders in tables --> + <xsl:param name="table.frame.border.thickness">0.1pt</xsl:param> + <xsl:param name="table.cell.border.thickness">0.1pt</xsl:param> + +<!--################################################### + Labels + ################################################### --> + +<!-- Label Chapters and Sections (numbering) --> + <xsl:param name="chapter.autolabel" select="1"/> + <xsl:param name="section.autolabel" select="1"/> + <xsl:param name="section.autolabel.max.depth" select="1"/> + + <xsl:param name="section.label.includes.component.label" select="1"/> + <xsl:param name="table.footnote.number.format" select="'1'"/> + +<!--################################################### + Programlistings + ################################################### --> + +<!-- Verbatim text formatting (programlistings) --> + <xsl:attribute-set name="monospace.verbatim.properties"> + <xsl:attribute name="font-size"> + <xsl:value-of select="$body.font.small * 0.90"/> + <xsl:text>pt</xsl:text> + </xsl:attribute> + </xsl:attribute-set> + + <xsl:attribute-set name="verbatim.properties"> + <xsl:attribute name="space-before.minimum">1em</xsl:attribute> + <xsl:attribute name="space-before.optimum">1em</xsl:attribute> + <xsl:attribute name="space-before.maximum">1em</xsl:attribute> + <xsl:attribute name="space-after.minimum">0.1em</xsl:attribute> + <xsl:attribute name="space-after.optimum">0.1em</xsl:attribute> + <xsl:attribute name="space-after.maximum">0.1em</xsl:attribute> + + <xsl:attribute name="border-color">#444444</xsl:attribute> + <xsl:attribute name="border-style">solid</xsl:attribute> + <xsl:attribute name="border-width">0.1pt</xsl:attribute> + <xsl:attribute name="padding-top">0.5em</xsl:attribute> + <xsl:attribute name="padding-left">0.5em</xsl:attribute> + <xsl:attribute name="padding-right">0.5em</xsl:attribute> + <xsl:attribute name="padding-bottom">0.5em</xsl:attribute> + <xsl:attribute name="margin-left">0em</xsl:attribute> + <xsl:attribute name="margin-right">0em</xsl:attribute> + </xsl:attribute-set> + + <!-- Shade (background) programlistings --> + <xsl:param name="shade.verbatim">1</xsl:param> + <xsl:attribute-set name="shade.verbatim.style"> + <xsl:attribute name="background-color">#F0F0F0</xsl:attribute> + </xsl:attribute-set> + + <xsl:attribute-set name="list.block.spacing"> + <xsl:attribute name="space-before.optimum">0.1em</xsl:attribute> + <xsl:attribute name="space-before.minimum">0.1em</xsl:attribute> + <xsl:attribute name="space-before.maximum">0.1em</xsl:attribute> + <xsl:attribute name="space-after.optimum">0.1em</xsl:attribute> + <xsl:attribute name="space-after.minimum">0.1em</xsl:attribute> + <xsl:attribute name="space-after.maximum">0.1em</xsl:attribute> + </xsl:attribute-set> + + <xsl:attribute-set name="abstract.properties"> + <xsl:attribute name="font-weight">normal</xsl:attribute> + </xsl:attribute-set> + + <xsl:attribute-set name="example.properties"> + <xsl:attribute name="space-before.minimum">0.5em</xsl:attribute> + <xsl:attribute name="space-before.optimum">0.5em</xsl:attribute> + <xsl:attribute name="space-before.maximum">0.5em</xsl:attribute> + <xsl:attribute name="space-after.minimum">0.1em</xsl:attribute> + <xsl:attribute name="space-after.optimum">0.1em</xsl:attribute> + <xsl:attribute name="space-after.maximum">0.1em</xsl:attribute> + <xsl:attribute name="keep-together.within-column">always</xsl:attribute> + </xsl:attribute-set> + +<!--################################################### + Title information for Figures, Examples etc. + ################################################### --> + + <xsl:attribute-set name="formal.title.properties" use-attribute-sets="normal.para.spacing"> + <xsl:attribute name="font-weight">normal</xsl:attribute> + <xsl:attribute name="font-style">italic</xsl:attribute> + <xsl:attribute name="font-size"> + <xsl:value-of select="$body.font.master"/> + <xsl:text>pt</xsl:text> + </xsl:attribute> + <xsl:attribute name="hyphenate">false</xsl:attribute> + <xsl:attribute name="space-before.minimum">0.1em</xsl:attribute> + <xsl:attribute name="space-before.optimum">0.1em</xsl:attribute> + <xsl:attribute name="space-before.maximum">0.1em</xsl:attribute> + </xsl:attribute-set> + +<!--################################################### + Callouts + ################################################### --> + +<!-- don't use images for callouts --> + <xsl:param name="callout.graphics">0</xsl:param> + <xsl:param name="callout.unicode">1</xsl:param> + +<!-- Place callout marks at this column in annotated areas --> + <xsl:param name="callout.defaultcolumn">90</xsl:param> + +<!--################################################### + Misc + ################################################### --> + +<!-- Placement of titles --> + <xsl:param name="formal.title.placement"> + figure after + example after + equation before + table before + procedure before + </xsl:param> + +<!-- Format Variable Lists as Blocks (prevents horizontal overflow) --> + <xsl:param name="variablelist.as.blocks">1</xsl:param> + + <xsl:param name="body.start.indent">0pt</xsl:param> + +<!-- Remove "Chapter" from the Chapter titles... --> + <xsl:param name="local.l10n.xml" select="document('')"/> + <l:i18n xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0"> + <l:l10n language="en"> + <l:context name="title-numbered"> + <l:template name="chapter" text="%n. %t"/> + <l:template name="section" text="%n %t"/> + </l:context> + <l:context name="title"> + <l:template name="example" text="Example %n %t"/> + </l:context> + </l:l10n> + </l:i18n> + +<!--################################################### + colored and hyphenated links + ################################################### --> + + <xsl:template match="ulink"> + <fo:basic-link external-destination="{@url}" + xsl:use-attribute-sets="xref.properties" + text-decoration="underline" + color="blue"> + <xsl:choose> + <xsl:when test="count(child::node())=0"> + <xsl:value-of select="@url"/> + </xsl:when> + <xsl:otherwise> + <xsl:apply-templates/> + </xsl:otherwise> + </xsl:choose> + </fo:basic-link> + </xsl:template> + + <xsl:template match="link"> + <fo:basic-link internal-destination="{@linkend}" + xsl:use-attribute-sets="xref.properties" + text-decoration="underline" + color="blue"> + <xsl:choose> + <xsl:when test="count(child::node())=0"> + <xsl:value-of select="@linkend"/> + </xsl:when> + <xsl:otherwise> + <xsl:apply-templates/> + </xsl:otherwise> + </xsl:choose> + </fo:basic-link> + </xsl:template> + +</xsl:stylesheet> \ No newline at end of file diff --git a/spring-build/docbook/styles/pdf/titlepage.xml b/spring-build/docbook/styles/pdf/titlepage.xml new file mode 100644 index 00000000000..b32d1ea6084 --- /dev/null +++ b/spring-build/docbook/styles/pdf/titlepage.xml @@ -0,0 +1,96 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<!DOCTYPE t:templates [ +<!ENTITY hsize0 "10pt"> +<!ENTITY hsize1 "12pt"> +<!ENTITY hsize2 "14.4pt"> +<!ENTITY hsize3 "17.28pt"> +<!ENTITY hsize4 "20.736pt"> +<!ENTITY hsize5 "24.8832pt"> +<!ENTITY hsize0space "7.5pt"> <!-- 0.75 * hsize0 --> +<!ENTITY hsize1space "9pt"> <!-- 0.75 * hsize1 --> +<!ENTITY hsize2space "10.8pt"> <!-- 0.75 * hsize2 --> +<!ENTITY hsize3space "12.96pt"> <!-- 0.75 * hsize3 --> +<!ENTITY hsize4space "15.552pt"> <!-- 0.75 * hsize4 --> +<!ENTITY hsize5space "18.6624pt"> <!-- 0.75 * hsize5 --> +]> +<t:templates xmlns:t="http://nwalsh.com/docbook/xsl/template/1.0" + xmlns:param="http://nwalsh.com/docbook/xsl/template/1.0/param" + xmlns:fo="http://www.w3.org/1999/XSL/Format" + xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> + + <t:titlepage t:element="book" t:wrapper="fo:block"> + <t:titlepage-content t:side="recto"> + <title + t:named-template="division.title" + param:node="ancestor-or-self::book[1]" + text-align="center" + font-size="&hsize5;" + space-before="&hsize5space;" + font-weight="bold" + font-family="{$title.fontset}" + /> + <subtitle + text-align="center" + font-size="&hsize4;" + space-before="&hsize4space;" + font-family="{$title.fontset}" + /> + + <corpauthor space-before="0.5em" + font-size="&hsize2;" + /> + + <authorgroup space-before="0.5em" + font-size="&hsize2;" + /> + + <author space-before="0.5em" font-size="&hsize2;"/> + <mediaobject space-before="2em" space-after="2em"/> + <releaseinfo space-before="5em" font-size="&hsize2;"/> + + <othercredit space-before="2em" font-weight="normal" font-size="8"/> + <pubdate space-before="0.5em"/> + <revision space-before="0.5em"/> + <revhistory space-before="0.5em"/> + + <abstract space-before="0.5em" + text-align="start" + margin-left="0.1in" + margin-right="0.1in" + font-family="{$body.fontset}" + /> + </t:titlepage-content> + + <t:titlepage-content t:side="verso" text-align="start"> + <copyright space-before="1.5em"/> + <legalnotice space-before="15em"/> + </t:titlepage-content> + + <t:titlepage-separator> + </t:titlepage-separator> + + <t:titlepage-before t:side="recto"> + </t:titlepage-before> + + <t:titlepage-before t:side="verso"> + </t:titlepage-before> + </t:titlepage> + +<!-- ==================================================================== --> + +</t:templates> diff --git a/spring-build/lib/ivy/commons-codec.jar b/spring-build/lib/ivy/commons-codec.jar new file mode 100644 index 0000000000000000000000000000000000000000..957b6752af9a60c1bb2a4f65db0e90e5ce00f521 GIT binary patch literal 46725 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 C?NEIH literal 0 HcmV?d00001 diff --git a/spring-build/lib/ivy/commons-httpclient.jar b/spring-build/lib/ivy/commons-httpclient.jar new file mode 100644 index 0000000000000000000000000000000000000000..7c59774aed4f5dd08778489aaad565690ff7c132 GIT binary patch literal 305001 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 tc`<nSD99iZcz#8> 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 literal 0 HcmV?d00001 diff --git a/spring-build/lib/ivy/commons-logging.jar b/spring-build/lib/ivy/commons-logging.jar new file mode 100644 index 0000000000000000000000000000000000000000..1deef144cb17ed2c11c6cdcdcb2d9530fa8d0b47 GIT binary patch literal 60686 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 YruOCyRJ0Q~M&J($Jhc`)ee&)90F*Xk_y7O^ literal 0 HcmV?d00001 diff --git a/spring-build/lib/ivy/current.version b/spring-build/lib/ivy/current.version new file mode 100644 index 00000000000..ebbc211dbb4 --- /dev/null +++ b/spring-build/lib/ivy/current.version @@ -0,0 +1,20 @@ +# Copyright 2010 SpringSource +# +# 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. + +ivy.jar= 2.1.0 +org.springframework.build.aws.ivy.jar= 1.0.8.RELEASE +commons-codec= 1.3.0 +commons-httpclient= 3.1.0 +commons-logging= 1.1.1 +jets3t= 0.7.0 diff --git a/spring-build/lib/ivy/ivy.jar b/spring-build/lib/ivy/ivy.jar new file mode 100644 index 0000000000000000000000000000000000000000..3902b6fdcd53892a7264c40f0a8246939de7ffc9 GIT binary patch literal 910990 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�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ⅈi(t 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 z%0A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 to(nB~K9Djjf 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�ol2QlGmXO7xpNg1>=?pY{cm4j-xV4V(o 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%0DQ)?L~a#ExsZat0UTUOX8_A5&d!jkOo3oWJsz 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 QF=Dy{Wk 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±*tNoi~f1%@cgk` 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 literal 0 HcmV?d00001 diff --git a/spring-build/lib/ivy/jets3t.jar b/spring-build/lib/ivy/jets3t.jar new file mode 100644 index 0000000000000000000000000000000000000000..3bab2985ce34f82cfadcd41b16f369623d7180b6 GIT binary patch literal 355132 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 literal 0 HcmV?d00001 diff --git a/spring-build/lib/ivy/jets3t.properties b/spring-build/lib/ivy/jets3t.properties new file mode 100644 index 00000000000..6a83275cf39 --- /dev/null +++ b/spring-build/lib/ivy/jets3t.properties @@ -0,0 +1,26 @@ +# Copyright 2010 SpringSource +# +# 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. + +## JetS3t Configuration Properties + +# A full description of all configuration properties can be found at +# http://jets3t.s3.amazonaws.com/toolkit/configuration.html + +# Proxy configuration +httpclient.proxy-autodetect=true +#httpclient.proxy-host= +#httpclient.proxy-port= +#httpclient.proxy-user= +#httpclient.proxy-password= +#httpclient.proxy-domain= diff --git a/spring-build/lib/ivy/org.springframework.build.aws.ivy.jar b/spring-build/lib/ivy/org.springframework.build.aws.ivy.jar new file mode 100644 index 0000000000000000000000000000000000000000..252d9a858741a0d2e45221d9189da4d8e55609bd GIT binary patch literal 7446 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 NA`s!=90<Sv`afY!;qd?f literal 0 HcmV?d00001 diff --git a/spring-build/library/artifact.xml b/spring-build/library/artifact.xml new file mode 100644 index 00000000000..96612d1c292 --- /dev/null +++ b/spring-build/library/artifact.xml @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="artifact-library" xmlns:ivy="antlib:org.apache.ivy.ant"> + + <import file="common.xml"/> + + <filterset id="library.filters" /> + +<!-- Main targets --> + <target name="javadoc-all" description="Does nothing"/> + + <target name="javadoc-api" description="Does nothing."/> + + <target name="jar" depends="ivy.init, resolve.compile" + description="Creates a libd file with the proper versions substituted."> + <delete quiet="true" file="${ivy.output.file}"/> + <mkdir dir="${ivy.output.dir}"/> + <delete quiet="true" file="${libd.output.file}"/> + <mkdir dir="${libd.output.dir}"/> + + <copy file="${libd.input.file}" tofile="${libd.output.file}"> + <filterset> + <filter token="bundle.version" value="${bundle.version}"/> + <filterset refid="library.filters"/> + </filterset> + </copy> + + <ivy:publish resolver="integration" pubdate="${timestamp}" status="${release.type}"> + <artifacts pattern="${ivy.output.dir}/[artifact].[ext]"/> + <artifacts pattern="${libd.output.dir}/[artifact].[ext]"/> + <artifacts pattern="${license.dir}/[artifact].[ext]"/> + </ivy:publish> + </target> + +<!-- Other targets --> + <target name="javadoc.prep"/> + +</project> diff --git a/spring-build/library/common.xml b/spring-build/library/common.xml new file mode 100644 index 00000000000..0f60ceed924 --- /dev/null +++ b/spring-build/library/common.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="common-library" xmlns:s="antlib:org.springframework.build"> + + <import file="../common/common.xml"/> + +</project> \ No newline at end of file diff --git a/spring-build/library/default.xml b/spring-build/library/default.xml new file mode 100644 index 00000000000..bf0f150bbd0 --- /dev/null +++ b/spring-build/library/default.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="default-library"> + + <import file="common.xml"/> + <import file="artifact.xml"/> + <import file="quality.xml"/> + <import file="package.xml"/> + <import file="publish.xml"/> + +</project> \ No newline at end of file diff --git a/spring-build/library/package.xml b/spring-build/library/package.xml new file mode 100644 index 00000000000..45e2b4fe0f2 --- /dev/null +++ b/spring-build/library/package.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="package-library"> + + <import file="common.xml"/> + <import file="../common/package.xml"/> + +<!-- Macros --> + <macrodef name="dist-jar"> + <attribute name="output.dir" default="${package.dist.dir}"/> + <sequential> + <mkdir dir="@{output.dir}"/> + <copy file="${libd.output.file}" tofile="@{output.dir}/${package.libd.output.file}"/> + </sequential> + </macrodef> + + <macrodef name="src-jar"> + <attribute name="output.dir" default="${package.src.dir}"/> + <sequential> + </sequential> + </macrodef> + +</project> \ No newline at end of file diff --git a/spring-build/library/publish.xml b/spring-build/library/publish.xml new file mode 100644 index 00000000000..adb505545ce --- /dev/null +++ b/spring-build/library/publish.xml @@ -0,0 +1,82 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="publish-library" xmlns:ivy="antlib:org.apache.ivy.ant" xmlns:maven="antlib:org.apache.maven.artifact.ant"> + + <import file="common.xml"/> + <import file="../common/publish.xml"/> + + <target name="publish-ivy" depends="ivy.init, resolve"> + <delete quiet="true" file="${ivy.output.file}"/> + <mkdir dir="${ivy.output.dir}" /> + + <ivy:publish resolver="${publication.resolver.prefix}-library-publish" pubdate="${timestamp}" + status="${release.type}"> + <artifacts pattern="${libd.output.dir}/[artifact].[ext]"/> + <artifacts pattern="${ivy.output.dir}/[artifact].[ext]"/> + <artifacts pattern="${license.dir}/[artifact].[ext]"/> + </ivy:publish> + </target> + + <target name="publish-maven" depends="create.pom, ivy.init, maven.init, resolve" unless="local.build"> + <maven:deploy file="${libd.output.file}"> + <remoteRepository url="s3://${publish.bucket}/maven/libraries/${adjusted.release.type}"> + <authentication username="${accessKey}" passphrase="${secretKey}"/> + </remoteRepository> + <pom file="${pom.output.file}"/> + </maven:deploy> + </target> + + <target name="publish-maven-central" depends="maven.init"> + <property name="maven.central.repository" value="s3://maven.springframework.org/${adjusted.release.type}"/> + <maven:deploy file="${libd.output.file}"> + <remoteRepository url="${maven.central.repository}"> + <authentication username="${accessKey}" passphrase="${secretKey}"/> + </remoteRepository> + <pom file="${local.pom.output.file}"/> + </maven:deploy> + </target> + + <target name="install-maven" depends="create.pom, snapshot.pom, maven.init"> + <maven:install file="${libd.output.file}"> + <pom file="${pom.output.file}"/> + </maven:install> + </target> + + <target name="install-maven-central" depends="maven.init"> + <maven:install file="${libd.output.file}"> + <pom file="${local.pom.output.file}"/> + </maven:install> + </target> + + <target name="create.pom" depends="ivy.init, resolve"> + <delete quiet="true" file="${pom.output.file}"/> + <mkdir dir="${pom.output.dir}"/> + + <ivy:makepom ivyfile="${ivy.output.file}" pomfile="${pom.output.file}"> + <mapping conf="compile" scope="compile"/> + <mapping conf="provided" scope="provided"/> + <mapping conf="dm-server-provided" scope="provided"/> + <mapping conf="runtime" scope="runtime"/> + <mapping conf="test" scope="test"/> + </ivy:makepom> + + <replaceregexp match="<packaging>jar</packaging>" + replace="<packaging>libd</packaging>" + file="${pom.output.file}"/> + </target> + +</project> \ No newline at end of file diff --git a/spring-build/library/quality.xml b/spring-build/library/quality.xml new file mode 100644 index 00000000000..6a7673f0b9f --- /dev/null +++ b/spring-build/library/quality.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="quality-library"> + +<!-- Main targets --> + <target name="test" description="Does nothing."/> + + <target name="clover" description="Does nothing."/> + + <target name="findbugs" description="Does nothing."/> + + <target name="osgi-validate" description="Does nothing."/> + +<!-- Other targets --> + <target name="test.do" description="Does nothing."/> + + <target name="clover.do" description="Does nothing."/> + + <target name="findbugs.do" description="Does nothing."/> + +</project> \ No newline at end of file diff --git a/spring-build/multi-bundle/artifact.xml b/spring-build/multi-bundle/artifact.xml new file mode 100644 index 00000000000..aeef1c32260 --- /dev/null +++ b/spring-build/multi-bundle/artifact.xml @@ -0,0 +1,70 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="artifact-multi-bundle"> + + <import file="common.xml"/> + +<!-- Main targets --> + <target name="javadoc-all" + description="Creates javadoc documentation for all classes."> + <delete dir="${javadoc-all.output.dir}" quiet="true"/> + <mkdir dir="${javadoc-all.output.dir}"/> + <all-bundles target="javadoc.prep"> + <property name="javadoc.prep.dir" value="${javadoc.prep.dir}"/> + </all-bundles> + <path id="global.path"> + <fileset dir="${ivy.cache.dir}" erroronmissingdir="false"> + <exclude name="**/*-sources-*.jar"/> + <include name="**/*.jar"/> + </fileset> + </path> + <java-doc input.dir="${javadoc.prep.dir}" output.dir="${javadoc-all.output.dir}" classpath.id="global.path" + access="private"/> + <delete quiet="true" dir="${javadoc.prep.dir}"/> + </target> + + <target name="javadoc-api" + description="Creates javadoc documentation for all classes."> + <delete dir="${javadoc-api.output.dir}" quiet="true"/> + <mkdir dir="${javadoc-api.output.dir}"/> + <all-bundles target="javadoc.prep"> + <property name="javadoc.prep.dir" value="${javadoc.prep.dir}"/> + </all-bundles> + <path id="global.path"> + <fileset dir="${ivy.cache.dir}" erroronmissingdir="false"> + <exclude name="**/*-sources-*.jar"/> + <include name="**/*.jar"/> + </fileset> + </path> + <java-doc input.dir="${javadoc.prep.dir}" output.dir="${javadoc-api.output.dir}" classpath.id="global.path" + access="protected" exclude.package.names="${javadoc.exclude.package.names}"/> + <delete quiet="true" dir="${javadoc.prep.dir}"/> + </target> + + <target name="jar" + description="Creates a JAR file containing the output of a compilation of the source tree."> + <all-bundles target="jar"/> + </target> + +<!-- Other targets --> + <target name="javadoc.prep"> + <all-bundles target="javadoc.prep"> + <property name="javadoc.prep.dir" value="${javadoc.prep.dir}"/> + </all-bundles> + </target> + +</project> \ No newline at end of file diff --git a/spring-build/multi-bundle/common.xml b/spring-build/multi-bundle/common.xml new file mode 100644 index 00000000000..e1d72134a3f --- /dev/null +++ b/spring-build/multi-bundle/common.xml @@ -0,0 +1,120 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="common-multi-bundle" xmlns:ivy="antlib:org.apache.ivy.ant"> + + <tstamp> + <format property="timestamp" pattern="yyyyMMddHHmmss" timezone="GMT"/> + </tstamp> + +<!-- Properties --> + <dirname property="spring.build.dir" file="${ant.file.common-multi-bundle}/.."/> + <property file="${spring.build.dir}/common/common.properties"/> + +<!-- Global targets --> + <condition property="adjusted.release.type" value="snapshot" else="${release.type}"> + <equals arg1="integration" arg2="${release.type}"/> + </condition> + +<!-- Main targets --> + <target name="clean" + description="Removes the target directory."> + <delete quiet="true" dir="${target.dir}"/> + <all-bundles target="clean"/> + </target> + + <target name="clean-integration" + description="Removes the integration repository directory."> + <fail message="The 'integration.repo.dir' property must be set on this project."> + <condition> + <not> + <isset property="integration.repo.dir"/> + </not> + </condition> + </fail> + <delete quiet="true" dir="${integration.repo.dir}"/> + </target> + + <target name="clean-ivy" depends="ivy.init" + description="Removes the ivy cache directory."> + <fail message="The 'ivy.cache.dir' property must be set on this project."> + <condition> + <not> + <isset property="ivy.cache.dir"/> + </not> + </condition> + </fail> + <delete quiet="true" dir="${ivy.cache.dir}"/> + </target> + +<!-- Other targets --> + <target name="ivy.init" unless="ivy.initialized"> + <taskdef resource="org/apache/ivy/ant/antlib.xml" uri="antlib:org.apache.ivy.ant"> + <classpath> + <path location="${ivy.lib.dir}/ivy.jar"/> + <path location="${ivy.lib.dir}/org.springframework.build.aws.ivy.jar"/> + <path location="${ivy.lib.dir}/commons-codec.jar"/> + <path location="${ivy.lib.dir}/commons-httpclient.jar"/> + <path location="${ivy.lib.dir}/commons-logging.jar"/> + <path location="${ivy.lib.dir}/jets3t.jar"/> + <path location="${ivy.lib.dir}"/> + </classpath> + </taskdef> + <ivy:settings file="${ivy.settings.file}"/> + <property name="ivy.initialized" value="true"/> + </target> + +<!-- Macros --> + <macrodef name="all-bundles"> + <attribute name="target"/> + <attribute name="buildpathRef" default="bundles"/> + <element name="inherited-properties" optional="true" implicit="true"/> + <sequential> + <subant target="@{target}" verbose="true" buildpathRef="@{buildpathRef}"> + <inherited-properties/> + <propertyset> + <propertyref builtin="commandline"/> + </propertyset> + <property name="timestamp" value="${timestamp}"/> + </subant> + </sequential> + </macrodef> + + <macrodef name="java-doc"> + <attribute name="input.dir"/> + <attribute name="output.dir"/> + <attribute name="classpath.id"/> + <attribute name="access"/> + <attribute name="exclude.package.names" default=""/> + <sequential> + <delete quiet="true" dir="@{output.dir}"/> + <mkdir dir="@{output.dir}"/> + <javadoc.links sourcepath="@{input.dir}" destdir="@{output.dir}" classpathref="@{classpath.id}" + access="@{access}" excludepackagenames="@{exclude.package.names}" maxmemory="${javadoc.max.memory}" + stylesheetfile="${javadoc.stylesheet.file}" splitindex="true" useexternalfile="true"> + <header><![CDATA[<!-- Begin Google Analytics code --> <script type="text/javascript"> var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www."); document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E")); </script> <script type="text/javascript"> var pageTracker = _gat._getTracker("UA-2728886-3"); pageTracker._setDomainName("none"); pageTracker._setAllowLinker(true); pageTracker._trackPageview(); </script> <!-- End Google Analytics code -->]]></header> + </javadoc.links> + <copy toDir="@{output.dir}/resources"> + <fileset dir="${javadoc.resources.dir}" erroronmissingdir="false"/> + </copy> + </sequential> + </macrodef> + + <presetdef name="javadoc.links"> + <javadoc/> + </presetdef> + +</project> \ No newline at end of file diff --git a/spring-build/multi-bundle/default.xml b/spring-build/multi-bundle/default.xml new file mode 100644 index 00000000000..67fc181c2a1 --- /dev/null +++ b/spring-build/multi-bundle/default.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="default-multi-bundle"> + + <import file="common.xml"/> + <import file="artifact.xml"/> + <import file="quality.xml"/> + <import file="package.xml"/> + <import file="publish.xml"/> + +</project> \ No newline at end of file diff --git a/spring-build/multi-bundle/package.xml b/spring-build/multi-bundle/package.xml new file mode 100644 index 00000000000..05550219281 --- /dev/null +++ b/spring-build/multi-bundle/package.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="package-multi-bundle"> + + <import file="common.xml"/> + +<!-- Main targets --> + <target name="package" + description="Creates a packaged distributable of the project. Unless overridden, delegates to sub-bundles."> + <all-bundles target="package"> + <property name="package.output.dir" value="${package.output.dir}"/> + </all-bundles> + </target> + +</project> \ No newline at end of file diff --git a/spring-build/multi-bundle/publish.xml b/spring-build/multi-bundle/publish.xml new file mode 100644 index 00000000000..012e121ed13 --- /dev/null +++ b/spring-build/multi-bundle/publish.xml @@ -0,0 +1,83 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="publish-multi-bundle" xmlns:ivy="antlib:org.apache.ivy.ant" + xmlns:aws="antlib:org.springframework.build.aws"> + + <import file="common.xml"/> + +<!-- Main targets --> + <target name="publish" + description="Publishes all artifacts to remote repositories"> + <all-bundles target="publish"/> + </target> + + <target name="publish-ivy" + description="Publishes all ivy artifacts to remote repositories"> + <all-bundles target="publish-ivy"/> + </target> + + <target name="publish-maven" + description="Publishes all maven artifacts to remote repositories"> + <all-bundles target="publish-maven"/> + </target> + + <target name="publish-maven-central"> + <all-bundles target="publish-maven-central"/> + </target> + + <target name="install-maven"> + <all-bundles target="install-maven"/> + </target> + + <target name="install-maven-central"> + <all-bundles target="install-maven-central"/> + </target> + + <target name="publish-package" depends="aws.init"> + <fail message="The 'project.name' property must be set on this project."> + <condition> + <not> + <isset property="project.name"/> + </not> + </condition> + </fail> + <checksum file="${package.output.file}" algorithm="sha1"/> + <aws:s3 accessKey="${accessKey}" secretKey="${secretKey}"> + <upload bucketName="dist.${bucket.basename}" file="${package.output.file}" + toFile="${adjusted.release.type}/${project.key}/${package.file.name}" publicRead="true"> + <metadata name="project.name" value="${project.name}"/> + <metadata name="release.type" value="${release.type}"/> + <metadata name="bundle.version" value="${bundle.version}"/> + <metadata name="package.file.name" value="${package.file.name}"/> + </upload> + <upload bucketName="dist.${bucket.basename}" file="${package.output.file}.sha1" + toFile="${adjusted.release.type}/${project.key}/${package.file.name}.sha1" publicRead="true"> + </upload> + </aws:s3> + </target> + +<!-- Other targets --> + <target name="aws.init" depends="ivy.init"> + <ivy:cachepath resolveId="spring.aws.ant.classpath" pathid="spring.aws.ant.classpath" + organisation="org.springframework.build" module="org.springframework.build.aws.ant" + revision="${org.springframework.build.aws.ant.version}" conf="runtime" type="jar" inline="true" + log="download-only"/> + <taskdef resource="org/springframework/build/aws/ant/antlib.xml" uri="antlib:org.springframework.build.aws" + classpathref="spring.aws.ant.classpath" /> + </target> + +</project> \ No newline at end of file diff --git a/spring-build/multi-bundle/quality.xml b/spring-build/multi-bundle/quality.xml new file mode 100644 index 00000000000..d0606d38ee7 --- /dev/null +++ b/spring-build/multi-bundle/quality.xml @@ -0,0 +1,138 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="quality-multi-bundle" xmlns:ivy="antlib:org.apache.ivy.ant"> + + <import file="common.xml"/> + +<!-- Main targets --> + <target name="test" depends="jar, test.pre, test.do, test.post" + description="Executes all tests resulting from a compilation of the test tree returning test success metrics."/> + + <target name="clover" depends="clover.pre, clover.do, clover.post" + description="Executes all tests resulting from a compilation of the test tree returning test coverage metrics."/> + + <target name="findbugs" depends="findbugs.pre, findbugs.do" + description="Checks all code from the source tree for bugs."/> + + <target name="osgi-validate" + description="Checks all code from the source tree for bugs."> + <all-bundles target="osgi-validate"/> + </target> + +<!-- Other targets --> + <target name="test.pre"> + <delete quiet="true" dir="${test-results.output.dir}"/> + <mkdir dir="${test-results.output.dir}/xml"/> + </target> + + <target name="test.do"> + <all-bundles target="test.do"> + <property name="test-results.output.dir" value="${test-results.output.dir}"/> + </all-bundles> + </target> + + <target name="test.post"> + <mkdir dir="${test-results.output.dir}/html"/> + <junitreport> + <fileset dir="${test-results.output.dir}/xml" erroronmissingdir="false"/> + <report format="frames" todir="${test-results.output.dir}/html"/> + </junitreport> + <delete file="TESTS-TestSuites.xml"/> + </target> + + <target name="clover.init" depends="ivy.init"> + <ivy:cachepath resolveId="clover.classpath" pathid="clover.classpath" organisation="com.atlassian.clover" + module="com.springsource.com.cenqua.clover" revision="${com.springsource.com.cenqua.clover.version}" + conf="runtime" type="jar" inline="true" log="download-only"/> + <taskdef resource="cloverlib.xml" classpathref="clover.classpath"/> + </target> + + <target name="clover.pre" depends="clover.init"> + <delete dir="${clover.output.dir}" quiet="true"/> + <mkdir dir="${clover.db.dir}"/> + </target> + + <target name="clover.do"> + <condition property="has.unit.test.bundles"> + <isreference refid="unit.test.bundles" /> + </condition> + <antcall target="clover.do.unit"/> + <antcall target="clover.do.all" /> + </target> + + <target name="clover.do.unit" if="has.unit.test.bundles"> + <all-bundles target="clover" buildpathRef="unit.test.bundles"/> + </target> + + <target name="clover.do.all" unless="has.unit.test.bundles"> + <all-bundles target="clover" buildpathRef="bundles"/> + </target> + + <target name="clover.post" depends="clover.init"> + <clover-merge initString="${clover.db.file}"> + <cloverDbSet dir="${basedir}/.." span="30m"> + <include name="**/target/clover/db/clover.db"/> + </cloverDbSet> + </clover-merge> + <clover-report initstring="${clover.db.file}"> + <current outfile="${clover.output.dir}/clover.xml" span="30m"> + <format type="xml"/> + <testsources dir=".."> + <include name="**/src/test/java/**/*.java"/> + <include name="**/src/test/java/*.java"/> + </testsources> + </current> + </clover-report> + <clover-report initstring="${clover.db.file}"> + <current outfile="${clover.output.dir}/html" span="30m"> + <format type="html"/> + <testsources dir=".."> + <include name="**/src/test/java/**/*.java"/> + <include name="**/src/test/java/*.java"/> + </testsources> + </current> + </clover-report> + <clover-report initstring="${clover.db.file}"> + <current outfile="${clover.output.dir}/clover.pdf" summary="true" span="30m"> + <format type="pdf"/> + <testsources dir=".."> + <include name="**/src/test/java/**/*.java"/> + <include name="**/src/test/java/*.java"/> + </testsources> + </current> + </clover-report> + <clover-check initstring="${clover.db.file}" target="${clover.coverage}" haltOnFailure="${clover.enforce}" + span="30m"> + <testsources dir=".."> + <include name="**/src/test/java/**/*.java"/> + <include name="**/src/test/java/*.java"/> + </testsources> + </clover-check> + </target> + + <target name="findbugs.pre"> + <delete dir="${findbugs.output.dir}" quiet="true"/> + <mkdir dir="${findbugs.output.dir}"/> + </target> + + <target name="findbugs.do"> + <all-bundles target="findbugs.do"> + <property name="findbugs.output.dir" value="${findbugs.output.dir}"/> + </all-bundles> + </target> + +</project> \ No newline at end of file diff --git a/spring-build/par/artifact.xml b/spring-build/par/artifact.xml new file mode 100644 index 00000000000..3714e91fbce --- /dev/null +++ b/spring-build/par/artifact.xml @@ -0,0 +1,66 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="artifact-par" xmlns:ivy="antlib:org.apache.ivy.ant"> + + <import file="common.xml"/> + <import file="../multi-bundle/artifact.xml"/> + +<!-- Main targets --> + <target name="jar" depends="ivy.init" + description="Creates a PAR file containing the output of the list of bundles."> + <delete dir="${par.staging.dir}" quiet="true"/> + <mkdir dir="${par.staging.dir}"/> + <delete dir="${par.output.file}" quiet="true"/> + <mkdir dir="${jar.output.dir}"/> + + <all-bundles target="jar"/> + <all-bundles target="copy-dist-jar"> + <property name="copy.to.dir" value="${par.staging.dir}"/> + </all-bundles> + <all-bundles target="copy-ext-jars"> + <property name="copy.to.dir" value="${par.staging.dir}"/> + </all-bundles> + <antcall target="collect-additional"/> + <jar destfile="${par.output.file}" basedir="${par.staging.dir}" index="true" filesetmanifest="merge"> + <manifest> + <attribute name="Application-SymbolicName" value="${ant.project.name}"/> + <attribute name="Application-Version" value="${bundle.version}"/> + <attribute name="Application-Name" value="${application.name}"/> + <attribute name="Application-Description" value="${application.description}"/> + <attribute name="Application-Creator" value="${user.name}"/> + </manifest> + </jar> + </target> + + <target name="collect-additional" depends="ivy.file.exists" if="ivy.file.exists"> + <add-jars output.dir="${par.staging.dir}"/> + </target> + + <target name="collect-provided" + description="Collects all the JARs expected to be provided for a PAR file."> + <delete dir="${par.provided.dir}" quiet="true"/> + <mkdir dir="${par.provided.dir}"/> + + <all-bundles target="copy-provided-jars"> + <property name="copy.to.dir" value="${par.provided.bundles.dir}"/> + </all-bundles> + <all-bundles target="copy-provided-libs"> + <property name="copy.to.dir" value="${par.provided.libraries.dir}"/> + </all-bundles> + </target> + +</project> \ No newline at end of file diff --git a/spring-build/par/common.xml b/spring-build/par/common.xml new file mode 100644 index 00000000000..c0447e42cb8 --- /dev/null +++ b/spring-build/par/common.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="common-par"> + + <import file="../multi-bundle/common.xml"/> + +</project> \ No newline at end of file diff --git a/spring-build/par/default.xml b/spring-build/par/default.xml new file mode 100644 index 00000000000..813a7927fb6 --- /dev/null +++ b/spring-build/par/default.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="default-par"> + + <import file="common.xml"/> + <import file="artifact.xml"/> + <import file="quality.xml"/> + <import file="package.xml"/> + <import file="publish.xml"/> + +</project> \ No newline at end of file diff --git a/spring-build/par/package.xml b/spring-build/par/package.xml new file mode 100644 index 00000000000..580a0e194c1 --- /dev/null +++ b/spring-build/par/package.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="package-par"> + + <import file="common.xml"/> + <import file="../common/package.xml"/> + +<!-- Macros --> + <macrodef name="dist-jar"> + <attribute name="output.dir" default="${package.dist.dir}"/> + <sequential> + <mkdir dir="@{output.dir}"/> + <copy file="${par.output.file}" tofile="@{output.dir}/${package.par.output.file}"/> + </sequential> + </macrodef> + +</project> \ No newline at end of file diff --git a/spring-build/par/publish.xml b/spring-build/par/publish.xml new file mode 100644 index 00000000000..da62d96dadb --- /dev/null +++ b/spring-build/par/publish.xml @@ -0,0 +1,66 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="publish-par" xmlns:ivy="antlib:org.apache.ivy.ant" xmlns:maven="antlib:org.apache.maven.artifact.ant"> + + <import file="common.xml"/> + <import file="../common/publish.xml"/> + + <target name="publish-ivy" depends="ivy.init, resolve"> + <delete quiet="true" file="${ivy.output.file}"/> + <mkdir dir="${ivy.output.dir}" /> + + <ivy:publish resolver="${publication.resolver.prefix}-bundle-publish" pubdate="${timestamp}" + status="${release.type}"> + <artifacts pattern="${par.output.dir}/[artifact].[ext]"/> + <artifacts pattern="${source-jar.output.dir}/[artifact].[ext]"/> + <artifacts pattern="${ivy.output.dir}/[artifact].[ext]"/> + <artifacts pattern="${license.dir}/[artifact].[ext]"/> + </ivy:publish> + </target> + + <target name="publish-maven" depends="create.pom, ivy.init, maven.init, resolve" unless="local.build"> + <maven:deploy file="${par.output.file}"> + <remoteRepository url="s3://${publish.bucket}/maven/bundles/${adjusted.release.type}"> + <authentication username="${accessKey}" passphrase="${secretKey}"/> + </remoteRepository> + <pom file="${pom.output.file}"/> + </maven:deploy> + </target> + + <target name="publish-maven-central" depends="maven.init"> + <property name="maven.central.repository" value="s3://maven.springframework.org/${adjusted.release.type}"/> + <maven:deploy file="${par.output.file}"> + <remoteRepository url="${maven.central.repository}"> + <authentication username="${accessKey}" passphrase="${secretKey}"/> + </remoteRepository> + <pom file="${local.pom.output.file}"/> + </maven:deploy> + </target> + + <target name="install-maven" depends="create.pom, snapshot.pom, maven.init"> + <maven:install file="${par.output.file}"> + <pom file="${pom.output.file}"/> + </maven:install> + </target> + + <target name="install-maven-central" depends="maven.init"> + <maven:install file="${par.output.file}"> + <pom file="${local.pom.output.file}"/> + </maven:install> + </target> + +</project> \ No newline at end of file diff --git a/spring-build/par/quality.xml b/spring-build/par/quality.xml new file mode 100644 index 00000000000..88e52ced975 --- /dev/null +++ b/spring-build/par/quality.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="quality-par"> + + <import file="common.xml"/> + <import file="../multi-bundle/quality.xml"/> + +</project> \ No newline at end of file diff --git a/spring-build/resource/artifact.xml b/spring-build/resource/artifact.xml new file mode 100644 index 00000000000..3ed7d817cb4 --- /dev/null +++ b/spring-build/resource/artifact.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="artifact-resource" xmlns:ivy="antlib:org.apache.ivy.ant"> + + <import file="common.xml"/> + +<!-- Main targets --> + <target name="javadoc-all" description="Does nothing"/> + + <target name="javadoc-api" description="Does nothing."/> + + <target name="jar" depends="ivy.init, resolve.compile" + description="Creates a libd file with the proper versions substituted."> + <delete quiet="true" file="${ivy.output.file}"/> + <mkdir dir="${ivy.output.dir}"/> + + <copy toDir="${artifacts.dir}"> + <fileset dir="${resource.src.dir}" erroronmissingdir="false"/> + </copy> + + <ivy:publish resolver="integration" pubdate="${timestamp}" status="${release.type}"> + <artifacts pattern="${ivy.output.dir}/[artifact].[ext]"/> + <artifacts pattern="${artifacts.dir}/[artifact].[ext]"/> + <artifacts pattern="${license.dir}/[artifact].[ext]"/> + </ivy:publish> + </target> + +<!-- Other targets --> + <target name="javadoc.prep"/> + +</project> diff --git a/spring-build/resource/common.xml b/spring-build/resource/common.xml new file mode 100644 index 00000000000..26a0181b3c9 --- /dev/null +++ b/spring-build/resource/common.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="common-resource" xmlns:s="antlib:org.springframework.build"> + + <import file="../common/common.xml"/> + +</project> \ No newline at end of file diff --git a/spring-build/resource/default.xml b/spring-build/resource/default.xml new file mode 100644 index 00000000000..be89f7019ec --- /dev/null +++ b/spring-build/resource/default.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="default-resource"> + + <import file="common.xml"/> + <import file="artifact.xml"/> + <import file="quality.xml"/> + <import file="package.xml"/> + <import file="publish.xml"/> + +</project> \ No newline at end of file diff --git a/spring-build/resource/package.xml b/spring-build/resource/package.xml new file mode 100644 index 00000000000..97197266c80 --- /dev/null +++ b/spring-build/resource/package.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="package-resource"> + + <import file="common.xml"/> + <import file="../common/package.xml"/> + +<!-- Macros --> + <macrodef name="dist-jar"> + <attribute name="output.dir" default="${package.dist.dir}"/> + <sequential> + <mkdir dir="@{output.dir}"/> + <copy todir="@{output.dir}"> + <fileset dir="${resource.src.dir}" /> + </copy> + </sequential> + </macrodef> + + <macrodef name="src-jar"> + <attribute name="output.dir" default="${package.src.dir}"/> + <sequential> + </sequential> + </macrodef> + +</project> \ No newline at end of file diff --git a/spring-build/resource/publish.xml b/spring-build/resource/publish.xml new file mode 100644 index 00000000000..52a3d994898 --- /dev/null +++ b/spring-build/resource/publish.xml @@ -0,0 +1,82 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="publish-resource" xmlns:ivy="antlib:org.apache.ivy.ant" xmlns:maven="antlib:org.apache.maven.artifact.ant"> + + <import file="common.xml"/> + <import file="../common/publish.xml"/> + + <target name="publish-ivy" depends="ivy.init, resolve"> + <delete quiet="true" file="${ivy.output.file}"/> + <mkdir dir="${ivy.output.dir}" /> + + <ivy:publish resolver="${publication.resolver.prefix}-library-publish" pubdate="${timestamp}" + status="${release.type}"> + <artifacts pattern="${artifacts.dir}/[artifact].[ext]"/> + <artifacts pattern="${ivy.output.dir}/[artifact].[ext]"/> + <artifacts pattern="${license.dir}/[artifact].[ext]"/> + </ivy:publish> + </target> + + <target name="publish-maven" depends="create.pom, ivy.init, maven.init, resolve" unless="local.build"> + <maven:deploy> + <remoteRepository url="s3://${publish.bucket}/maven/libraries/${adjusted.release.type}"> + <authentication username="${accessKey}" passphrase="${secretKey}"/> + </remoteRepository> + <pom file="${pom.output.file}"/> + </maven:deploy> + </target> + + <target name="publish-maven-central" depends="maven.init"> + <property name="maven.central.repository" value="s3://maven.springframework.org/${adjusted.release.type}"/> + <maven:deploy> + <remoteRepository url="${maven.central.repository}"> + <authentication username="${accessKey}" passphrase="${secretKey}"/> + </remoteRepository> + <pom file="${local.pom.output.file}"/> + </maven:deploy> + </target> + + <target name="install-maven" depends="create.pom, snapshot.pom, maven.init"> + <maven:install> + <pom file="${pom.output.file}"/> + </maven:install> + </target> + + <target name="install-maven-central" depends="maven.init"> + <maven:install> + <pom file="${local.pom.output.file}"/> + </maven:install> + </target> + + <target name="create.pom" depends="ivy.init, resolve"> + <delete quiet="true" file="${pom.output.file}"/> + <mkdir dir="${pom.output.dir}"/> + + <ivy:makepom ivyfile="${ivy.output.file}" pomfile="${pom.output.file}"> + <mapping conf="compile" scope="compile"/> + <mapping conf="provided" scope="provided"/> + <mapping conf="dm-server-provided" scope="provided"/> + <mapping conf="runtime" scope="runtime"/> + <mapping conf="test" scope="test"/> + </ivy:makepom> + + <replaceregexp match="<packaging>jar</packaging>" + replace="<packaging>pom</packaging>" + file="${pom.output.file}"/> + </target> + +</project> \ No newline at end of file diff --git a/spring-build/resource/quality.xml b/spring-build/resource/quality.xml new file mode 100644 index 00000000000..291d89c1e0d --- /dev/null +++ b/spring-build/resource/quality.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="quality-resource"> + +<!-- Main targets --> + <target name="test" description="Does nothing."/> + + <target name="clover" description="Does nothing."/> + + <target name="findbugs" description="Does nothing."/> + + <target name="osgi-validate" description="Does nothing."/> + +<!-- Other targets --> + <target name="test.do" description="Does nothing."/> + + <target name="clover.do" description="Does nothing."/> + + <target name="findbugs.do" description="Does nothing."/> + +</project> \ No newline at end of file diff --git a/spring-build/standard/artifact.xml b/spring-build/standard/artifact.xml new file mode 100644 index 00000000000..5d6de512cf5 --- /dev/null +++ b/spring-build/standard/artifact.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="artifact-standard" xmlns:ivy="antlib:org.apache.ivy.ant"> + + <import file="common.xml"/> + <import file="../common/artifact.xml"/> + + +<!-- Other targets --> + <target name="compile.init" depends="ivy.init"> + <ivy:cachepath resolveId="spring.ant.classpath" pathid="spring.ant.classpath" + organisation="org.springframework.build" module="org.springframework.build.ant" + revision="${org.springframework.build.ant.version}" conf="runtime" type="jar" inline="true" + log="download-only"/> + <ivy:cachepath resolveId="ecj.classpath" pathid="ecj.classpath" organisation="org.eclipse.jdt" + module="com.springsource.org.eclipse.jdt.core.compiler.batch" revision="${org.eclipse.jdt.core.compiler.batch.version}" + conf="runtime" type="jar" inline="true" log="download-only"/> + <taskdef resource="org/springframework/build/ant/antlib.xml" uri="antlib:org.springframework.build"> + <classpath> + <path refid="spring.ant.classpath"/> + <path refid="ecj.classpath"/> + </classpath> + </taskdef> + </target> + +</project> \ No newline at end of file diff --git a/spring-build/standard/common.xml b/spring-build/standard/common.xml new file mode 100644 index 00000000000..44d9fdb3020 --- /dev/null +++ b/spring-build/standard/common.xml @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="common-standard" xmlns:s="antlib:org.springframework.build"> + + <import file="../common/common.xml"/> + +<!-- Macros --> + <macrodef name="do-compile"> + <attribute name="classpath.id"/> + <attribute name="input.dir"/> + <attribute name="output.dir"/> + <attribute name="resources.dir"/> + <sequential> + <s:javac destdir="@{output.dir}" source="${source.version}" target="${target.version}" + debug="${compile.debug}" debugLevel="${compile.debug.level}"> + <compilerarg line="${compiler.args}"/> + <src path="@{input.dir}"/> + <include name="**/*.java"/> + <include name="*.java"/> + <classpath refid="@{classpath.id}"/> + </s:javac> + <copy todir="@{output.dir}"> + <fileset dir="@{input.dir}" erroronmissingdir="false"> + <exclude name="**/*.java"/> + <exclude name="*.java"/> + </fileset> + </copy> + <copy todir="@{output.dir}"> + <fileset dir="@{resources.dir}" erroronmissingdir="false"/> + </copy> + </sequential> + </macrodef> + +</project> \ No newline at end of file diff --git a/spring-build/standard/default.xml b/spring-build/standard/default.xml new file mode 100644 index 00000000000..b93cc846956 --- /dev/null +++ b/spring-build/standard/default.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="default-standard"> + + <import file="common.xml"/> + <import file="artifact.xml"/> + <import file="quality.xml"/> + <import file="package.xml"/> + <import file="publish.xml"/> + +</project> \ No newline at end of file diff --git a/spring-build/standard/package.xml b/spring-build/standard/package.xml new file mode 100644 index 00000000000..1fc8ed40403 --- /dev/null +++ b/spring-build/standard/package.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="package-standard"> + + <import file="common.xml"/> + <import file="../common/package.xml"/> + +</project> \ No newline at end of file diff --git a/spring-build/standard/publish.xml b/spring-build/standard/publish.xml new file mode 100644 index 00000000000..3fae574a48c --- /dev/null +++ b/spring-build/standard/publish.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="publish-standard"> + + <import file="common.xml"/> + <import file="../common/publish.xml"/> + +</project> \ No newline at end of file diff --git a/spring-build/standard/quality.xml b/spring-build/standard/quality.xml new file mode 100644 index 00000000000..b84c71c958a --- /dev/null +++ b/spring-build/standard/quality.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="quality-standard"> + + <import file="common.xml"/> + <import file="../common/quality.xml"/> + +</project> \ No newline at end of file diff --git a/spring-build/war/artifact.xml b/spring-build/war/artifact.xml new file mode 100644 index 00000000000..8d65ee4583f --- /dev/null +++ b/spring-build/war/artifact.xml @@ -0,0 +1,85 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="artifact-war" xmlns:ivy="antlib:org.apache.ivy.ant" xmlns:bundlor="antlib:com.springsource.bundlor.ant"> + + <import file="common.xml"/> + <import file="../common/artifact.xml"/> + +<!-- Main targets --> + <target name="jar" depends="ivy.init, resolve.compile, compile.init, jar.init" + description="Creates a WAR file containing the output of a compilation of the source tree."> + <delete quiet="true" file="${ivy.output.file}"/> + <mkdir dir="${ivy.output.dir}"/> + <delete quiet="true" file="${war.output.file}"/> + <mkdir dir="${war.output.dir}"/> + <delete quiet="true" file="${source-jar.output.file}"/> + <mkdir dir="${source-jar.output.dir}"/> + + <copy todir="${war.staging.dir}"> + <fileset dir="${main.webapp.dir}" erroronmissingdir="false"/> + </copy> + + <compile classpath.id="compile.classpath" input.dir="${main.java.dir}" output.dir="${war.classes.dir}" + resources.dir="${main.resources.dir}"/> + <ivy:retrieve resolveId="compile.classpath" conf="compile,runtime" type="jar" + pattern="${war.lib.dir}/[artifact]-[revision].[ext]" log="download-only"/> + <antcall target="bundlor"/> + <jar destfile="${war.output.file}" basedir="${war.staging.dir}" index="true" filesetmanifest="merge"> + <manifest> + <attribute name="Bundle-Creator" value="${user.name}"/> + <attribute name="Implementation-Title" value="${implementation.title}"/> + <attribute name="Implementation-Version" value="${implementation.version}"/> + </manifest> + </jar> + <jar destfile="${source-jar.output.file}" basedir="${main.java.dir}" index="true"/> + <ivy:publish resolver="integration" pubdate="${timestamp}" status="${release.type}"> + <artifacts pattern="${ivy.output.dir}/[artifact].[ext]"/> + <artifacts pattern="${war.output.dir}/[artifact].[ext]"/> + <artifacts pattern="${source-jar.output.dir}/[artifact].[ext]"/> + <artifacts pattern="${license.dir}/[artifact].[ext]"/> + </ivy:publish> + </target> + +<!-- Other targets --> + <target name="compile.init" depends="ivy.init"> + <ivy:cachepath resolveId="spring.ant.classpath" pathid="spring.ant.classpath" + organisation="org.springframework.build" module="org.springframework.build.ant" + revision="${org.springframework.build.ant.version}" conf="runtime" type="jar" inline="true" + log="download-only"/> + <ivy:cachepath resolveId="ecj.classpath" pathid="ecj.classpath" organisation="org.eclipse.jdt" + module="com.springsource.org.eclipse.jdt.core.compiler.batch" revision="${org.eclipse.jdt.core.compiler.batch.version}" + conf="runtime" type="jar" inline="true" log="download-only"/> + <taskdef resource="org/springframework/build/ant/antlib.xml" uri="antlib:org.springframework.build"> + <classpath> + <path refid="spring.ant.classpath"/> + <path refid="ecj.classpath"/> + </classpath> + </taskdef> + </target> + + <target name="bundlor" depends="bundlor.init" unless="disable.bundlor"> + <bundlor:bundlor inputPath="${war.staging.dir}" outputPath="${war.staging.dir}" + bundleVersion="${bundle.version}" manifestTemplatePath="${manifest.template.file}" + failOnWarnings="${fail.on.warnings}"> + <propertyset refid="bundlor.properties"/> + <propertyset> + <propertyref builtin="all"/> + </propertyset> + </bundlor:bundlor> + </target> + +</project> \ No newline at end of file diff --git a/spring-build/war/common.xml b/spring-build/war/common.xml new file mode 100644 index 00000000000..dbe930ba03d --- /dev/null +++ b/spring-build/war/common.xml @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="common-war" xmlns:s="antlib:org.springframework.build"> + + <import file="../common/common.xml"/> + +<!-- Macros --> + <macrodef name="do-compile"> + <attribute name="classpath.id"/> + <attribute name="input.dir"/> + <attribute name="output.dir"/> + <attribute name="resources.dir"/> + <sequential> + <s:javac destdir="@{output.dir}" source="${source.version}" target="${target.version}" + debug="${compile.debug}" debugLevel="${compile.debug.level}"> + <compilerarg line="${compiler.args}"/> + <src path="@{input.dir}"/> + <include name="**/*.java"/> + <include name="*.java"/> + <classpath refid="@{classpath.id}"/> + </s:javac> + <copy todir="@{output.dir}"> + <fileset dir="@{input.dir}" erroronmissingdir="false"> + <exclude name="**/*.java"/> + <exclude name="*.java"/> + </fileset> + </copy> + <copy todir="@{output.dir}"> + <fileset dir="@{resources.dir}" erroronmissingdir="false"/> + </copy> + </sequential> + </macrodef> + +</project> \ No newline at end of file diff --git a/spring-build/war/default.xml b/spring-build/war/default.xml new file mode 100644 index 00000000000..8f0965f501c --- /dev/null +++ b/spring-build/war/default.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="default-war"> + + <import file="common.xml"/> + <import file="artifact.xml"/> + <import file="quality.xml"/> + <import file="package.xml"/> + <import file="publish.xml"/> + +</project> \ No newline at end of file diff --git a/spring-build/war/package.xml b/spring-build/war/package.xml new file mode 100644 index 00000000000..05ea4813b1e --- /dev/null +++ b/spring-build/war/package.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="package-war"> + + <import file="common.xml"/> + <import file="../common/package.xml"/> + +<!-- Macros --> + <macrodef name="dist-jar"> + <attribute name="output.dir" default="${package.dist.dir}"/> + <sequential> + <mkdir dir="@{output.dir}"/> + <copy file="${war.output.file}" tofile="@{output.dir}/${package.war.output.file}"/> + </sequential> + </macrodef> + +</project> \ No newline at end of file diff --git a/spring-build/war/publish.xml b/spring-build/war/publish.xml new file mode 100644 index 00000000000..0d2386235c9 --- /dev/null +++ b/spring-build/war/publish.xml @@ -0,0 +1,70 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="publish-war" xmlns:ivy="antlib:org.apache.ivy.ant" xmlns:maven="antlib:org.apache.maven.artifact.ant"> + + <import file="common.xml"/> + <import file="../common/publish.xml"/> + + <target name="publish-ivy" depends="ivy.init, resolve"> + <delete quiet="true" file="${ivy.output.file}"/> + <mkdir dir="${ivy.output.dir}" /> + + <ivy:publish resolver="${publication.resolver.prefix}-bundle-publish" pubdate="${timestamp}" + status="${release.type}"> + <artifacts pattern="${war.output.dir}/[artifact].[ext]"/> + <artifacts pattern="${source-jar.output.dir}/[artifact].[ext]"/> + <artifacts pattern="${ivy.output.dir}/[artifact].[ext]"/> + <artifacts pattern="${license.dir}/[artifact].[ext]"/> + </ivy:publish> + </target> + + <target name="publish-maven" depends="create.pom, snapshot.pom, maven.init" unless="local.build"> + <maven:deploy file="${war.output.file}"> + <remoteRepository url="s3://${publish.bucket}/maven/bundles/${adjusted.release.type}"> + <authentication username="${accessKey}" passphrase="${secretKey}"/> + </remoteRepository> + <pom file="${pom.output.file}"/> + <attach file="${source-jar.output.file}" classifier="sources"/> + </maven:deploy> + </target> + + <target name="publish-maven-central" depends="maven.init"> + <property name="maven.central.repository" value="s3://maven.springframework.org/${adjusted.release.type}"/> + <maven:deploy file="${war.output.file}"> + <remoteRepository url="${maven.central.repository}"> + <authentication username="${accessKey}" passphrase="${secretKey}"/> + </remoteRepository> + <pom file="${local.pom.output.file}"/> + <attach file="${source-jar.output.file}" classifier="sources"/> + </maven:deploy> + </target> + + <target name="install-maven" depends="create.pom, snapshot.pom, maven.init"> + <maven:install file="${war.output.file}"> + <pom file="${pom.output.file}"/> + <attach file="${source-jar.output.file}" classifier="sources"/> + </maven:install> + </target> + + <target name="install-maven-central" depends="maven.init"> + <maven:install file="${war.output.file}"> + <pom file="${local.pom.output.file}"/> + <attach file="${source-jar.output.file}" classifier="sources"/> + </maven:install> + </target> + +</project> \ No newline at end of file diff --git a/spring-build/war/quality.xml b/spring-build/war/quality.xml new file mode 100644 index 00000000000..7c673b228f5 --- /dev/null +++ b/spring-build/war/quality.xml @@ -0,0 +1,74 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="quality-war" xmlns:ivy="antlib:org.apache.ivy.ant" xmlns:osgi="antlib:org.springframework.build.osgi"> + + <import file="common.xml"/> + <import file="../common/quality.xml"/> + + <target name="osgi-validate" depends="ivy.init, osgi.init" + description="Validates that a bundle can resolve against it's dependencies."> + <ivy:cachepath resolveId="osgi.optional.classpath" pathid="osgi.optional.classpath" + conf="compile,optional,provided,dm-server-provided" type="jar" log="download-only"/> + <osgi:validate bundlePath="${war.output.file}"> + <equinoxPath refid="equinox.classpath"/> + <supportingBundlesPath refid="osgi.optional.classpath"/> + </osgi:validate> + + <ivy:cachepath resolveId="osgi.compile.classpath" pathid="osgi.compile.classpath" + conf="compile,provided,dm-server-provided" type="jar" log="download-only"/> + <osgi:validate bundlePath="${war.output.file}"> + <equinoxPath refid="equinox.classpath"/> + <supportingBundlesPath refid="osgi.compile.classpath"/> + </osgi:validate> + </target> + +<!-- Other targets --> + <target name="test.do" depends="ivy.init, resolve.test, compile.init, test.init" if="test.exists"> + <path id="test.compile.classpath"> + <pathelement location="${war.classes.dir}"/> + <path refid="compile.classpath"/> + <path refid="test.classpath"/> + </path> + <test-compile classpath.id="test.compile.classpath" input.dir="${test.java.dir}" output.dir="${test.output.dir}" + resources.dir="${test.resources.dir}"/> + + <path id="test.run.classpath"> + <pathelement location="${war.classes.dir}"/> + <pathelement location="${test.output.dir}"/> + <path refid="compile.classpath"/> + <path refid="test.classpath"/> + <path refid="runtime.classpath"/> + </path> + <test-run classpath.id="test.run.classpath"/> + </target> + + <target name="findbugs.do" depends="ivy.init, resolve.compile, compile.init, findbugs.init, src.init" if="src.exists"> + <findbugs home="${findbugs.dir}" output="xml" outputFile="${findbugs.output.file}" + excludeFilter="${findbugs.exclude.file}" jvmargs="-Xmx1024M" errorProperty="findbugs.errors" warningsProperty="findbugs.warnings"> + <class location="${war.classes.dir}"/> + <auxClasspath refid="compile.classpath"/> + <sourcepath location="${main.java.dir}"/> + </findbugs> + <antcall target="findbugs.post"/> + </target> + + <target name="findbugs.post" if="findbugs.enforce"> + <fail if="findbugs.errors" message="FindBugs errors found"/> + <fail if="findbugs.warnings" message="FindBugs warnings found"/> + </target> + +</project> \ No newline at end of file diff --git a/spring-build/weaving-external/artifact.xml b/spring-build/weaving-external/artifact.xml new file mode 100644 index 00000000000..f0511cf97c6 --- /dev/null +++ b/spring-build/weaving-external/artifact.xml @@ -0,0 +1,83 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="artifact-weaving-external" xmlns:ivy="antlib:org.apache.ivy.ant" + xmlns:bundlor="antlib:com.springsource.bundlor.ant"> + + <import file="common.xml"/> + <import file="../common/artifact.xml"/> + + <target name="javadoc-all" + description="Creates javadoc documentation for all classes."/> + + <target name="jar" depends="ivy.init, resolve.compile, resolve.aspects, resolve.external, compile.init, jar.init" + description="Creates a JAR file containing the output of a compilation of the source tree."> + <delete quiet="true" file="${ivy.output.file}"/> + <mkdir dir="${ivy.output.dir}"/> + <delete quiet="true" file="${jar.output.file}"/> + <mkdir dir="${jar.output.dir}"/> + <delete quiet="true" file="${source-jar.output.file}"/> + <mkdir dir="${source-jar.output.dir}"/> + + <iajc inPathRef="external.classpath" aspectPathRef="aspects.classpath" classpathRef="compile.classpath" + outJar="${jar.output.file}" source="${source.version}" checkRuntimeVersion="false" X="${aspectj.x}"/> + <antcall target="bundlor"/> + <copy tofile="${source-jar.output.file}"> + <path refid="external.srcpath"/> + <flattenmapper/> + </copy> + <ivy:publish resolver="integration" pubdate="${timestamp}" status="${release.type}" overwrite="true"> + <artifacts pattern="${ivy.output.dir}/[artifact].[ext]"/> + <artifacts pattern="${jar.output.dir}/[artifact].[ext]"/> + <artifacts pattern="${source-jar.output.dir}/[artifact].[ext]"/> + <artifacts pattern="${license.dir}/[artifact].[ext]"/> + </ivy:publish> + </target> + +<!-- Other targets --> + <target name="compile.init" depends="ivy.init"> + <ivy:cachepath resolveId="ajc.classpath" pathid="ajc.classpath" organisation="org.aspectj" + module="com.springsource.org.aspectj.tools" revision="${org.aspectj.tools.version}" conf="runtime" + type="jar" inline="true" log="download-only"/> + <taskdef resource="org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties" classpathref="ajc.classpath"/> + + <ivy:cachepath resolveId="spring.ant.classpath" pathid="spring.ant.classpath" + organisation="org.springframework.build" module="org.springframework.build.ant" + revision="${org.springframework.build.ant.version}" conf="runtime" type="jar" inline="true" + log="download-only"/> + <ivy:cachepath resolveId="ecj.classpath" pathid="ecj.classpath" organisation="org.eclipse.jdt" + module="com.springsource.org.eclipse.jdt.core.compiler.batch" revision="${org.eclipse.jdt.core.compiler.batch.version}" + conf="runtime" type="jar" inline="true" log="download-only"/> + <taskdef resource="org/springframework/build/ant/antlib.xml" uri="antlib:org.springframework.build"> + <classpath> + <path refid="spring.ant.classpath"/> + <path refid="ecj.classpath"/> + </classpath> + </taskdef> + </target> + + <target name="bundlor" depends="bundlor.init" unless="disable.bundlor"> + <bundlor:bundlor inputPath="${jar.output.file}" outputPath="${jar.output.file}" + bundleVersion="${bundle.version}" manifestTemplatePath="${manifest.template.file}" + failOnWarnings="${fail.on.warnings}"> + <propertyset refid="bundlor.properties"/> + <propertyset> + <propertyref builtin="all"/> + </propertyset> + </bundlor:bundlor> + </target> + +</project> \ No newline at end of file diff --git a/spring-build/weaving-external/common.xml b/spring-build/weaving-external/common.xml new file mode 100644 index 00000000000..ada91806baf --- /dev/null +++ b/spring-build/weaving-external/common.xml @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="common-weaving-external" xmlns:s="antlib:org.springframework.build"> + + <import file="../common/common.xml"/> + +<!-- Macros --> + <macrodef name="do-compile"> + <attribute name="classpath.id"/> + <attribute name="input.dir"/> + <attribute name="output.dir"/> + <attribute name="resources.dir"/> + <sequential> + <s:javac destdir="@{output.dir}" source="${source.version}" target="${target.version}" + debug="${compile.debug}" debugLevel="${compile.debug.level}"> + <compilerarg line="${compiler.args}"/> + <src path="@{input.dir}"/> + <include name="**/*.java"/> + <include name="*.java"/> + <classpath refid="@{classpath.id}"/> + </s:javac> + <copy todir="@{output.dir}"> + <fileset dir="@{input.dir}" erroronmissingdir="false"> + <exclude name="**/*.java"/> + <exclude name="*.java"/> + </fileset> + </copy> + <copy todir="@{output.dir}"> + <fileset dir="@{resources.dir}" erroronmissingdir="false"/> + </copy> + </sequential> + </macrodef> + +</project> \ No newline at end of file diff --git a/spring-build/weaving-external/default.xml b/spring-build/weaving-external/default.xml new file mode 100644 index 00000000000..3b88f098c39 --- /dev/null +++ b/spring-build/weaving-external/default.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="default-weaving-external"> + + <import file="common.xml"/> + <import file="artifact.xml"/> + <import file="quality.xml"/> + <import file="package.xml"/> + <import file="publish.xml"/> + +</project> \ No newline at end of file diff --git a/spring-build/weaving-external/package.xml b/spring-build/weaving-external/package.xml new file mode 100644 index 00000000000..09009d69f08 --- /dev/null +++ b/spring-build/weaving-external/package.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="package-weaving-external"> + + <import file="common.xml"/> + <import file="../common/package.xml"/> + +</project> \ No newline at end of file diff --git a/spring-build/weaving-external/publish.xml b/spring-build/weaving-external/publish.xml new file mode 100644 index 00000000000..fd58c241571 --- /dev/null +++ b/spring-build/weaving-external/publish.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="publish-weaving-external"> + + <import file="common.xml"/> + <import file="../common/publish.xml"/> + +</project> \ No newline at end of file diff --git a/spring-build/weaving-external/quality.xml b/spring-build/weaving-external/quality.xml new file mode 100644 index 00000000000..2b5a0261779 --- /dev/null +++ b/spring-build/weaving-external/quality.xml @@ -0,0 +1,63 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="quality-weaving-external" xmlns:ivy="antlib:org.apache.ivy.ant"> + + <import file="common.xml"/> + <import file="../common/quality.xml"/> + +<!-- Other targets --> + <target name="test.do" depends="ivy.init, resolve.test, compile.init, test.init" if="test.exists"> + <path id="test.compile.classpath"> + <pathelement location="${jar.output.file}"/> + <path refid="test.classpath"/> + </path> + <test-compile classpath.id="test.compile.classpath" input.dir="${test.java.dir}" output.dir="${test.output.dir}" + resources.dir="${test.resources.dir}"/> + + <path id="test.run.classpath"> + <pathelement location="${jar.output.file}"/> + <pathelement location="${test.output.dir}"/> + <path refid="test.classpath"/> + <path refid="runtime.classpath"/> + </path> + <test-run classpath.id="test.run.classpath"/> + </target> + + <target name="clover.do" depends="ivy.init, resolve.test, compile.init, clover.init, clover.instrument, test.init" + if="test.exists"> + <path id="clover.run.classpath"> + <pathelement location="${jar.output.file}"/> + <pathelement location="${test.output.dir}"/> + <path refid="clover.classpath"/> + <path refid="test.classpath"/> + <path refid="runtime.classpath"/> + </path> + <test-run classpath.id="clover.run.classpath"/> + </target> + + <target name="clover.instrument" depends="ivy.init, resolve.test, compile.init, clover.init"> + <instrument input.dir="${test.java.dir}" output.dir="${test.clover.dir}"/> + <path id="test.compile.classpath"> + <pathelement location="${main.output.dir}"/> + <path refid="test.classpath"/> + <path refid="clover.classpath"/> + </path> + <test-compile classpath.id="test.compile.classpath" input.dir="${test.clover.dir}" output.dir="${test.output.dir}" + resources.dir="${test.resources.dir}"/> + <delete dir="${clover.staging.dir}" quiet="true"/> + </target> +</project> \ No newline at end of file diff --git a/spring-build/weaving/artifact.xml b/spring-build/weaving/artifact.xml new file mode 100644 index 00000000000..478fe06c116 --- /dev/null +++ b/spring-build/weaving/artifact.xml @@ -0,0 +1,59 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="artifact-weaving" xmlns:ivy="antlib:org.apache.ivy.ant" + xmlns:bundlor="antlib:com.springsource.bundlor.ant"> + + <import file="common.xml"/> + <import file="../common/artifact.xml"/> + + <target name="jar" depends="ivy.init, resolve.aspects, artifact-common.jar" + description="Creates a JAR file containing the output of a compilation of the source tree."/> + +<!-- Other targets --> + <target name="compile.init" depends="ivy.init"> + <ivy:cachepath resolveId="ajc.classpath" pathid="ajc.classpath" organisation="org.aspectj" + module="com.springsource.org.aspectj.tools" revision="${org.aspectj.tools.version}" conf="runtime" + type="jar" inline="true" log="download-only"/> + <taskdef resource="org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties" classpathref="ajc.classpath"/> + + <ivy:cachepath resolveId="spring.ant.classpath" pathid="spring.ant.classpath" + organisation="org.springframework.build" module="org.springframework.build.ant" + revision="${org.springframework.build.ant.version}" conf="runtime" type="jar" inline="true" + log="download-only"/> + <ivy:cachepath resolveId="ecj.classpath" pathid="ecj.classpath" organisation="org.eclipse.jdt" + module="com.springsource.org.eclipse.jdt.core.compiler.batch" revision="${org.eclipse.jdt.core.compiler.batch.version}" + conf="runtime" type="jar" inline="true" log="download-only"/> + <taskdef resource="org/springframework/build/ant/antlib.xml" uri="antlib:org.springframework.build"> + <classpath> + <path refid="spring.ant.classpath"/> + <path refid="ecj.classpath"/> + </classpath> + </taskdef> + </target> + + <target name="bundlor" depends="bundlor.init" unless="disable.bundlor"> + <bundlor:bundlor inputPath="${main.output.dir}" outputPath="${main.output.dir}" + bundleVersion="${bundle.version}" manifestTemplatePath="${manifest.template.file}" + failOnWarnings="${fail.on.warnings}"> + <propertyset refid="bundlor.properties"/> + <propertyset> + <propertyref builtin="all"/> + </propertyset> + </bundlor:bundlor> + </target> + +</project> \ No newline at end of file diff --git a/spring-build/weaving/common.xml b/spring-build/weaving/common.xml new file mode 100644 index 00000000000..9d27767759c --- /dev/null +++ b/spring-build/weaving/common.xml @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="common-weaving" xmlns:s="antlib:org.springframework.build"> + + <import file="../common/common.xml"/> + +<!-- Macros --> + <macrodef name="do-compile"> + <attribute name="classpath.id"/> + <attribute name="input.dir"/> + <attribute name="output.dir"/> + <attribute name="resources.dir"/> + <sequential> + <s:javac destdir="@{output.dir}" source="${source.version}" target="${target.version}" + debug="${compile.debug}" debugLevel="${compile.debug.level}"> + <compilerarg line="${compiler.args}"/> + <src path="@{input.dir}"/> + <include name="**/*.java"/> + <include name="*.java"/> + <classpath refid="@{classpath.id}"/> + </s:javac> + <copy todir="@{output.dir}"> + <fileset dir="@{input.dir}" erroronmissingdir="false"> + <exclude name="**/*.java"/> + <exclude name="*.java"/> + </fileset> + </copy> + <copy todir="@{output.dir}"> + <fileset dir="@{resources.dir}" erroronmissingdir="false"/> + </copy> + <iajc inPath="${main.output.dir}" aspectPathRef="aspects.classpath" classpathRef="compile.classpath" + destDir="${main.output.dir}" source="${source.version}" checkRuntimeVersion="false" X="${aspectj.x}"/> + </sequential> + </macrodef> + +</project> \ No newline at end of file diff --git a/spring-build/weaving/default.xml b/spring-build/weaving/default.xml new file mode 100644 index 00000000000..c4dc8ed9c37 --- /dev/null +++ b/spring-build/weaving/default.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="default-weaving"> + + <import file="common.xml"/> + <import file="artifact.xml"/> + <import file="quality.xml"/> + <import file="package.xml"/> + <import file="publish.xml"/> + +</project> \ No newline at end of file diff --git a/spring-build/weaving/package.xml b/spring-build/weaving/package.xml new file mode 100644 index 00000000000..764a5f143e2 --- /dev/null +++ b/spring-build/weaving/package.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="package-weaving"> + + <import file="common.xml"/> + <import file="../common/package.xml"/> + +</project> \ No newline at end of file diff --git a/spring-build/weaving/publish.xml b/spring-build/weaving/publish.xml new file mode 100644 index 00000000000..42f3bd05615 --- /dev/null +++ b/spring-build/weaving/publish.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="publish-weaving"> + + <import file="common.xml"/> + <import file="../common/publish.xml"/> + +</project> \ No newline at end of file diff --git a/spring-build/weaving/quality.xml b/spring-build/weaving/quality.xml new file mode 100644 index 00000000000..20cae52bb97 --- /dev/null +++ b/spring-build/weaving/quality.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright 2010 SpringSource + + 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. +--> +<project name="quality-weaving" xmlns:ivy="antlib:org.apache.ivy.ant"> + + <import file="common.xml"/> + <import file="../common/quality.xml"/> + + <target name="clover.instrument" depends="ivy.init, resolve.aspects, quality-common.clover.instrument" + description="Creates a JAR file containing the output of a compilation of the source tree."/> + + <target name="test.do" depends="ivy.init, resolve.test, resolve.aspects, compile.init, test.init" if="test.exists"> + <path id="test.compile.classpath"> + <pathelement location="${jar.output.file}"/> + <path refid="compile.classpath"/> + <path refid="test.classpath"/> + </path> + <test-compile classpath.id="test.compile.classpath" input.dir="${test.java.dir}" output.dir="${test.output.dir}" + resources.dir="${test.resources.dir}"/> + + <path id="test.run.classpath"> + <pathelement location="${jar.output.file}"/> + <pathelement location="${test.output.dir}"/> + <path refid="compile.classpath"/> + <path refid="test.classpath"/> + <path refid="runtime.classpath"/> + <path refid="aspects.classpath"/> + </path> + <test-run classpath.id="test.run.classpath"/> + </target> + +</project> \ No newline at end of file From dfc5b482c90c262c71d4d208d21dabdfc2e50f13 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller <jhoeller@vmware.com> Date: Thu, 15 Dec 2011 23:47:45 +0100 Subject: [PATCH 03/22] IntelliJ IDEA 11 project setup --- .../test/util/ReflectionTestUtilsTests.java | 15 +- spring-framework.ipr | 2351 +++++++++-------- 2 files changed, 1217 insertions(+), 1149 deletions(-) diff --git a/org.springframework.test/src/test/java/org/springframework/test/util/ReflectionTestUtilsTests.java b/org.springframework.test/src/test/java/org/springframework/test/util/ReflectionTestUtilsTests.java index f707fdc40cf..f4d25452ade 100644 --- a/org.springframework.test/src/test/java/org/springframework/test/util/ReflectionTestUtilsTests.java +++ b/org.springframework.test/src/test/java/org/springframework/test/util/ReflectionTestUtilsTests.java @@ -203,21 +203,24 @@ public class ReflectionTestUtilsTests { @Test public void invokeMethodWithAutoboxingAndUnboxing() { - int difference = invokeMethod(component, "subtract", 5, 2); - assertEquals("subtract(5, 2)", 3, difference); + // IntelliJ IDEA 11 won't accept int assignment here + Integer difference = invokeMethod(component, "subtract", 5, 2); + assertEquals("subtract(5, 2)", 3, difference.intValue()); } @Ignore("[SPR-8644] findMethod() does not currently support var-args") @Test public void invokeMethodWithPrimitiveVarArgs() { - int sum = invokeMethod(component, "add", 1, 2, 3, 4); - assertEquals("add(1,2,3,4)", 10, sum); + // IntelliJ IDEA 11 won't accept int assignment here + Integer sum = invokeMethod(component, "add", 1, 2, 3, 4); + assertEquals("add(1,2,3,4)", 10, sum.intValue()); } @Test public void invokeMethodWithPrimitiveVarArgsAsSingleArgument() { - int sum = invokeMethod(component, "add", new int[] { 1, 2, 3, 4 }); - assertEquals("add(1,2,3,4)", 10, sum); + // IntelliJ IDEA 11 won't accept int assignment here + Integer sum = invokeMethod(component, "add", new int[] { 1, 2, 3, 4 }); + assertEquals("add(1,2,3,4)", 10, sum.intValue()); } @Test diff --git a/spring-framework.ipr b/spring-framework.ipr index b5ce1ca4858..afc4643b983 100644 --- a/spring-framework.ipr +++ b/spring-framework.ipr @@ -1,1143 +1,1208 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project version="4"> - <component name="AntConfiguration"> - <defaultAnt bundledAnt="true" /> - </component> - <component name="BuildJarProjectSettings"> - <option name="BUILD_JARS_ON_MAKE" value="false" /> - </component> - <component name="ChangeBrowserSettings"> - <option name="MAIN_SPLITTER_PROPORTION" value="0.3" /> - <option name="MESSAGES_SPLITTER_PROPORTION" value="0.8" /> - <option name="USE_DATE_BEFORE_FILTER" value="false" /> - <option name="USE_DATE_AFTER_FILTER" value="false" /> - <option name="USE_CHANGE_BEFORE_FILTER" value="false" /> - <option name="USE_CHANGE_AFTER_FILTER" value="false" /> - <option name="DATE_BEFORE" value="" /> - <option name="DATE_AFTER" value="" /> - <option name="CHANGE_BEFORE" value="" /> - <option name="CHANGE_AFTER" value="" /> - <option name="USE_USER_FILTER" value="false" /> - <option name="USER" value="" /> - </component> - <component name="CodeStyleProjectProfileManger"> - <option name="PROJECT_PROFILE" /> - <option name="USE_PROJECT_LEVEL_SETTINGS" value="false" /> - </component> - <component name="CodeStyleSettingsManager"> - <option name="PER_PROJECT_SETTINGS"> - <value> - <option name="JAVA_INDENT_OPTIONS"> - <value> - <option name="INDENT_SIZE" value="4" /> - <option name="CONTINUATION_INDENT_SIZE" value="8" /> - <option name="TAB_SIZE" value="4" /> - <option name="USE_TAB_CHARACTER" value="true" /> - <option name="SMART_TABS" value="false" /> - <option name="LABEL_INDENT_SIZE" value="0" /> - <option name="LABEL_INDENT_ABSOLUTE" value="false" /> - <option name="USE_RELATIVE_INDENTS" value="false" /> - </value> - </option> - <option name="LINE_SEPARATOR" value=" " /> - <option name="PREFER_LONGER_NAMES" value="false" /> - <option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999" /> - <option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="1" /> - <option name="IMPORT_LAYOUT_TABLE"> - <value> - <package name="java" withSubpackages="true" static="false" /> - <package name="javax" withSubpackages="true" static="false" /> - <emptyLine /> - <package name="" withSubpackages="true" static="false" /> - <emptyLine /> - <package name="org.springframework" withSubpackages="true" static="false" /> - <emptyLine /> - <package name="" withSubpackages="true" static="true" /> - </value> - </option> - <option name="JD_ALIGN_PARAM_COMMENTS" value="false" /> - <option name="JD_ALIGN_EXCEPTION_COMMENTS" value="false" /> - <option name="JD_P_AT_EMPTY_LINES" value="false" /> - <option name="JD_DO_NOT_WRAP_ONE_LINE_COMMENTS" value="true" /> - <option name="JD_KEEP_EMPTY_PARAMETER" value="false" /> - <option name="JD_KEEP_EMPTY_EXCEPTION" value="false" /> - <option name="JD_KEEP_EMPTY_RETURN" value="false" /> - <option name="XML_KEEP_WHITESPACES" value="true" /> - <option name="XML_TEXT_WRAP" value="0" /> - <option name="KEEP_LINE_BREAKS" value="false" /> - <option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1" /> - <option name="KEEP_BLANK_LINES_IN_CODE" value="1" /> - <option name="BLANK_LINES_AROUND_FIELD" value="1" /> - <option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1" /> - <option name="ELSE_ON_NEW_LINE" value="true" /> - <option name="WHILE_ON_NEW_LINE" value="true" /> - <option name="CATCH_ON_NEW_LINE" value="true" /> - <option name="FINALLY_ON_NEW_LINE" value="true" /> - <option name="ALIGN_MULTILINE_PARAMETERS" value="false" /> - <option name="ALIGN_MULTILINE_FOR" value="false" /> - <option name="CALL_PARAMETERS_WRAP" value="1" /> - <option name="METHOD_PARAMETERS_WRAP" value="5" /> - <option name="EXTENDS_LIST_WRAP" value="1" /> - <option name="THROWS_LIST_WRAP" value="1" /> - <option name="EXTENDS_KEYWORD_WRAP" value="1" /> - <option name="THROWS_KEYWORD_WRAP" value="1" /> - <option name="METHOD_CALL_CHAIN_WRAP" value="1" /> - <option name="BINARY_OPERATION_WRAP" value="1" /> - <option name="TERNARY_OPERATION_WRAP" value="1" /> - <option name="FOR_STATEMENT_WRAP" value="5" /> - <option name="ARRAY_INITIALIZER_WRAP" value="1" /> - <option name="ASSIGNMENT_WRAP" value="1" /> - <option name="WRAP_COMMENTS" value="true" /> - <option name="IF_BRACE_FORCE" value="3" /> - <option name="DOWHILE_BRACE_FORCE" value="3" /> - <option name="WHILE_BRACE_FORCE" value="3" /> - <option name="FOR_BRACE_FORCE" value="3" /> - <ADDITIONAL_INDENT_OPTIONS fileType="groovy"> - <option name="INDENT_SIZE" value="2" /> - <option name="CONTINUATION_INDENT_SIZE" value="8" /> - <option name="TAB_SIZE" value="4" /> - <option name="USE_TAB_CHARACTER" value="false" /> - <option name="SMART_TABS" value="false" /> - <option name="LABEL_INDENT_SIZE" value="0" /> - <option name="LABEL_INDENT_ABSOLUTE" value="false" /> - <option name="USE_RELATIVE_INDENTS" value="false" /> - </ADDITIONAL_INDENT_OPTIONS> - <ADDITIONAL_INDENT_OPTIONS fileType="gsp"> - <option name="INDENT_SIZE" value="2" /> - <option name="CONTINUATION_INDENT_SIZE" value="8" /> - <option name="TAB_SIZE" value="4" /> - <option name="USE_TAB_CHARACTER" value="false" /> - <option name="SMART_TABS" value="false" /> - <option name="LABEL_INDENT_SIZE" value="0" /> - <option name="LABEL_INDENT_ABSOLUTE" value="false" /> - <option name="USE_RELATIVE_INDENTS" value="false" /> - </ADDITIONAL_INDENT_OPTIONS> - <ADDITIONAL_INDENT_OPTIONS fileType="java"> - <option name="INDENT_SIZE" value="4" /> - <option name="CONTINUATION_INDENT_SIZE" value="8" /> - <option name="TAB_SIZE" value="4" /> - <option name="USE_TAB_CHARACTER" value="true" /> - <option name="SMART_TABS" value="false" /> - <option name="LABEL_INDENT_SIZE" value="0" /> - <option name="LABEL_INDENT_ABSOLUTE" value="false" /> - <option name="USE_RELATIVE_INDENTS" value="false" /> - </ADDITIONAL_INDENT_OPTIONS> - <ADDITIONAL_INDENT_OPTIONS fileType="js"> - <option name="INDENT_SIZE" value="4" /> - <option name="CONTINUATION_INDENT_SIZE" value="8" /> - <option name="TAB_SIZE" value="4" /> - <option name="USE_TAB_CHARACTER" value="false" /> - <option name="SMART_TABS" value="false" /> - <option name="LABEL_INDENT_SIZE" value="0" /> - <option name="LABEL_INDENT_ABSOLUTE" value="false" /> - <option name="USE_RELATIVE_INDENTS" value="false" /> - </ADDITIONAL_INDENT_OPTIONS> - <ADDITIONAL_INDENT_OPTIONS fileType="jsp"> - <option name="INDENT_SIZE" value="4" /> - <option name="CONTINUATION_INDENT_SIZE" value="8" /> - <option name="TAB_SIZE" value="4" /> - <option name="USE_TAB_CHARACTER" value="false" /> - <option name="SMART_TABS" value="false" /> - <option name="LABEL_INDENT_SIZE" value="0" /> - <option name="LABEL_INDENT_ABSOLUTE" value="false" /> - <option name="USE_RELATIVE_INDENTS" value="false" /> - </ADDITIONAL_INDENT_OPTIONS> - <ADDITIONAL_INDENT_OPTIONS fileType="php"> - <option name="INDENT_SIZE" value="4" /> - <option name="CONTINUATION_INDENT_SIZE" value="8" /> - <option name="TAB_SIZE" value="4" /> - <option name="USE_TAB_CHARACTER" value="false" /> - <option name="SMART_TABS" value="false" /> - <option name="LABEL_INDENT_SIZE" value="0" /> - <option name="LABEL_INDENT_ABSOLUTE" value="false" /> - <option name="USE_RELATIVE_INDENTS" value="false" /> - </ADDITIONAL_INDENT_OPTIONS> - <ADDITIONAL_INDENT_OPTIONS fileType="sass"> - <option name="INDENT_SIZE" value="2" /> - <option name="CONTINUATION_INDENT_SIZE" value="8" /> - <option name="TAB_SIZE" value="4" /> - <option name="USE_TAB_CHARACTER" value="false" /> - <option name="SMART_TABS" value="false" /> - <option name="LABEL_INDENT_SIZE" value="0" /> - <option name="LABEL_INDENT_ABSOLUTE" value="false" /> - <option name="USE_RELATIVE_INDENTS" value="false" /> - </ADDITIONAL_INDENT_OPTIONS> - <ADDITIONAL_INDENT_OPTIONS fileType="sql"> - <option name="INDENT_SIZE" value="2" /> - <option name="CONTINUATION_INDENT_SIZE" value="8" /> - <option name="TAB_SIZE" value="4" /> - <option name="USE_TAB_CHARACTER" value="false" /> - <option name="SMART_TABS" value="false" /> - <option name="LABEL_INDENT_SIZE" value="0" /> - <option name="LABEL_INDENT_ABSOLUTE" value="false" /> - <option name="USE_RELATIVE_INDENTS" value="false" /> - </ADDITIONAL_INDENT_OPTIONS> - <ADDITIONAL_INDENT_OPTIONS fileType="txt"> - <option name="INDENT_SIZE" value="2" /> - <option name="CONTINUATION_INDENT_SIZE" value="8" /> - <option name="TAB_SIZE" value="4" /> - <option name="USE_TAB_CHARACTER" value="false" /> - <option name="SMART_TABS" value="false" /> - <option name="LABEL_INDENT_SIZE" value="0" /> - <option name="LABEL_INDENT_ABSOLUTE" value="false" /> - <option name="USE_RELATIVE_INDENTS" value="false" /> - </ADDITIONAL_INDENT_OPTIONS> - <ADDITIONAL_INDENT_OPTIONS fileType="xml"> - <option name="INDENT_SIZE" value="4" /> - <option name="CONTINUATION_INDENT_SIZE" value="8" /> - <option name="TAB_SIZE" value="4" /> - <option name="USE_TAB_CHARACTER" value="true" /> - <option name="SMART_TABS" value="false" /> - <option name="LABEL_INDENT_SIZE" value="0" /> - <option name="LABEL_INDENT_ABSOLUTE" value="false" /> - <option name="USE_RELATIVE_INDENTS" value="false" /> - </ADDITIONAL_INDENT_OPTIONS> - <ADDITIONAL_INDENT_OPTIONS fileType="yml"> - <option name="INDENT_SIZE" value="2" /> - <option name="CONTINUATION_INDENT_SIZE" value="8" /> - <option name="TAB_SIZE" value="4" /> - <option name="USE_TAB_CHARACTER" value="false" /> - <option name="SMART_TABS" value="false" /> - <option name="LABEL_INDENT_SIZE" value="0" /> - <option name="LABEL_INDENT_ABSOLUTE" value="false" /> - <option name="USE_RELATIVE_INDENTS" value="false" /> - </ADDITIONAL_INDENT_OPTIONS> - </value> - </option> - <option name="USE_PER_PROJECT_SETTINGS" value="true" /> - </component> - <component name="CompilerConfiguration"> - <option name="DEFAULT_COMPILER" value="Javac" /> - <resourceExtensions> - <entry name=".+\.(properties|xml|html|dtd|tld)" /> - <entry name=".+\.(gif|png|jpeg|jpg)" /> - </resourceExtensions> - <wildcardResourcePatterns> - <entry name="*.properties" /> - <entry name="*.txt" /> - <entry name="*.xml" /> - <entry name="*.gif" /> - <entry name="*.png" /> - <entry name="*.jpeg" /> - <entry name="*.jpg" /> - <entry name="*.html" /> - <entry name="*.css" /> - <entry name="*.js" /> - <entry name="*.dtd" /> - <entry name="*.xsd" /> - <entry name="*.tld" /> - <entry name="*.xls" /> - <entry name="*.vm" /> - <entry name="*.ftl" /> - <entry name="*.sql" /> - <entry name="*.types" /> - <entry name="*.bsh" /> - <entry name="*.rb" /> - <entry name="*.groovy" /> - <entry name="*.handlers" /> - <entry name="*.schemas" /> - </wildcardResourcePatterns> - <annotationProcessing enabled="false" useClasspath="true" /> - </component> - <component name="CopyrightManager" default="Spring"> - <copyright> - <option name="notice" value="Copyright 2002-&#36;today.year the original author or authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License." /> - <option name="keyword" value="Copyright" /> - <option name="allowReplaceKeyword" value="" /> - <option name="myName" value="Spring" /> - <option name="myLocal" value="true" /> - </copyright> - <module2copyright> - <element module="All" copyright="Spring" /> - </module2copyright> - <LanguageOptions name="HTML"> - <option name="fileTypeOverride" value="1" /> - </LanguageOptions> - <LanguageOptions name="JSP"> - <option name="fileTypeOverride" value="1" /> - </LanguageOptions> - <LanguageOptions name="JSPX"> - <option name="fileTypeOverride" value="1" /> - </LanguageOptions> - <LanguageOptions name="JavaScript"> - <option name="fileTypeOverride" value="1" /> - </LanguageOptions> - <LanguageOptions name="Properties"> - <option name="fileTypeOverride" value="1" /> - </LanguageOptions> - <LanguageOptions name="XML"> - <option name="fileTypeOverride" value="1" /> - </LanguageOptions> - </component> - <component name="DependenciesAnalyzeManager"> - <option name="myForwardDirection" value="false" /> - </component> - <component name="DependencyValidationManager"> - <option name="SKIP_IMPORT_STATEMENTS" value="false" /> - </component> - <component name="EclipseCompilerSettings"> - <option name="GENERATE_NO_WARNINGS" value="true" /> - </component> - <component name="EclipseEmbeddedCompilerSettings"> - <option name="DEBUGGING_INFO" value="true" /> - <option name="GENERATE_NO_WARNINGS" value="true" /> - <option name="DEPRECATION" value="false" /> - <option name="ADDITIONAL_OPTIONS_STRING" value="" /> - <option name="MAXIMUM_HEAP_SIZE" value="128" /> - </component> - <component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" /> - <component name="EntryPointsManager"> - <entry_points version="2.0" /> - </component> - <component name="ExportToHTMLSettings"> - <option name="PRINT_LINE_NUMBERS" value="false" /> - <option name="OPEN_IN_BROWSER" value="false" /> - <option name="OUTPUT_DIRECTORY" /> - </component> - <component name="FacetAutodetectingManager"> - <autodetection-disabled> - <facet-type id="Gant_Grails" /> - <facet-type id="Grails" /> - <facet-type id="Groovy" /> - <facet-type id="jpa"> - <modules> - <module name="integration-tests" /> - <module name="orm"> - <files> - <file url="file://$PROJECT_DIR$/org.springframework.orm/src/test/java/org/springframework/orm/jpa/META-INF/persistence.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.orm/src/test/java/org/springframework/orm/jpa/domain/persistence-context.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.orm/src/test/java/org/springframework/orm/jpa/domain/persistence-multi.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.orm/src/test/java/org/springframework/orm/jpa/domain/persistence.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.orm/src/test/java/org/springframework/orm/jpa/persistence-complex.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.orm/src/test/java/org/springframework/orm/jpa/persistence-example1.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.orm/src/test/java/org/springframework/orm/jpa/persistence-example2.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.orm/src/test/java/org/springframework/orm/jpa/persistence-example3.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.orm/src/test/java/org/springframework/orm/jpa/persistence-example4.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.orm/src/test/java/org/springframework/orm/jpa/persistence-example5.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.orm/src/test/java/org/springframework/orm/jpa/persistence-example6.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.orm/src/test/java/org/springframework/orm/jpa/persistence-invalid.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.orm/src/test/java/org/springframework/orm/jpa/persistence-no-schema.xml" /> - </files> - </module> - </modules> - </facet-type> - <facet-type id="Spring"> - <modules> - <module name="aop"> - <files> - <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/config/AopNamespaceHandlerEventTests-context.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/config/AopNamespaceHandlerEventTests-directPointcutEvents.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/config/AopNamespaceHandlerEventTests-pointcutEvents.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/config/AopNamespaceHandlerEventTests-pointcutRefEvents.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/config/AopNamespaceHandlerPointcutErrorTests-pointcutDuplication.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/config/AopNamespaceHandlerPointcutErrorTests-pointcutMissing.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/config/aopNamespaceHandlerAdvisorWithDirectPointcutEventTests.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/config/aopNamespaceHandlerAdvisorWithPointcutRefEventTests.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/config/aopNamespaceHandlerAspectEventTests.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/config/aopNamespaceHandlerPointcutDuplicationTests.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/config/aopNamespaceHandlerPointcutEventTests.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/config/aopNamespaceHandlerPointcutMissingTests.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/framework/PrototypeTargetTests-context.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/framework/prototypeTarget.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/interceptor/ExposeInvocationInterceptorTests-context.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/interceptor/exposeInvocation.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/scope/ScopedProxyAutowireTests-scopedAutowireFalse.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/scope/ScopedProxyAutowireTests-scopedAutowireTrue.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/scope/scopedAutowireFalse.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/scope/scopedAutowireTrue.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/support/RegexpMethodPointcutAdvisorIntegrationTests-context.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/support/regexpSetterTests.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/target/CommonsPoolTargetSourceProxyTests-context.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/target/HotSwappableTargetSourceTests-context.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/target/LazyInitTargetSourceTests-customTarget.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/target/LazyInitTargetSourceTests-factoryBean.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/target/LazyInitTargetSourceTests-singleton.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/target/PrototypeTargetSourceTests-context.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/target/ThreadLocalTargetSourceTests-context.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/target/commonsPoolProxyTests.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/target/customLazyInitTarget.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/target/hotSwapTests.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/target/lazyInitFactoryBean.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/target/lazyInitSingletonTests.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/target/prototypeTests.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/target/threadLocalTests.xml" /> - </files> - </module> - <module name="beans" /> - <module name="context" /> - <module name="context-support" /> - <module name="integration-tests" /> - <module name="jdbc" /> - <module name="jms" /> - <module name="org.springframework.integration-tests" /> - <module name="org.springframework.jdbc" /> - <module name="orm" /> - <module name="oxm"> - <files> - <file url="file://$PROJECT_DIR$/org.springframework.oxm/src/test/resources/org/springframework/oxm/config/oxmNamespaceHandlerTest.xml" /> - </files> - </module> - <module name="test" /> - <module name="transaction"> - <files> - <file url="file://$PROJECT_DIR$/org.springframework.transaction/src/test/java/org/springframework/transaction/annotation/annotationTransactionNamespaceHandlerTests.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.transaction/src/test/java/org/springframework/transaction/config/annotationDrivenProxyTargetClassTests.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.transaction/src/test/java/org/springframework/transaction/interceptor/noTransactionAttributeSource.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.transaction/src/test/java/org/springframework/transaction/interceptor/transactionalBeanFactory.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.transaction/src/test/java/org/springframework/transaction/txNamespaceHandlerTests.xml" /> - </files> - </module> - <module name="web"> - <files> - <file url="file://$PROJECT_DIR$/org.springframework.web/src/test/resources/org/springframework/web/context/request/requestScopeTests.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.web/src/test/resources/org/springframework/web/context/request/requestScopedProxyTests.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.web/src/test/resources/org/springframework/web/context/request/sessionScopeTests.xml" /> - </files> - </module> - <module name="web-portlet"> - <files> - <file url="file://$PROJECT_DIR$/org.springframework.web.portlet/src/test/java/org/springframework/web/portlet/context/WEB-INF/applicationContext.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.web.portlet/src/test/java/org/springframework/web/portlet/context/WEB-INF/empty-portlet.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.web.portlet/src/test/java/org/springframework/web/portlet/context/WEB-INF/resources/messageSource.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.web.portlet/src/test/java/org/springframework/web/portlet/context/WEB-INF/resources/themeSource.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.web.portlet/src/test/java/org/springframework/web/portlet/context/WEB-INF/test-portlet.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.web.portlet/src/test/java/org/springframework/web/portlet/context/WEB-INF/test-servlet.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.web.portlet/src/test/java/org/springframework/web/portlet/handler/parameterMapping.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.web.portlet/src/test/java/org/springframework/web/portlet/handler/portletModeMapping.xml" /> - <file url="file://$PROJECT_DIR$/org.springframework.web.portlet/src/test/java/org/springframework/web/portlet/handler/portletModeParameterMapping.xml" /> - </files> - </module> - <module name="web-servlet" /> - </modules> - </facet-type> - <facet-type id="web"> - <modules> - <module name="integration-tests" /> - <module name="org.springframework.integration-tests" /> - <module name="web-servlet"> - <files> - <file url="file://$PROJECT_DIR$/org.springframework.web.servlet/src/test/java/org/springframework/web/context/WEB-INF/web.xml" /> - </files> - </module> - </modules> - </facet-type> - </autodetection-disabled> - </component> - <component name="IdProvider" IDEtalkID="C2515F8F9A78051322E588EF85003B36" /> - <component name="InspectionProjectProfileManager"> - <profiles> - <profile version="1.0" is_locked="false"> - <option name="myName" value="Project Default" /> - <option name="myLocal" value="false" /> - <inspection_tool class="AssertsWithoutMessages" enabled="true" level="WARNING" enabled_by_default="true" /> - <inspection_tool class="ClassWithMultipleLoggers" enabled="true" level="WARNING" enabled_by_default="true"> - <option name="loggerNamesString" value="java.util.logging.Logger,org.slf4j.Logger,org.apache.commons.logging.Log,org.apache.log4j.Logger" /> - </inspection_tool> - <inspection_tool class="EqualsAndHashcode" enabled="true" level="WARNING" enabled_by_default="true" /> - <inspection_tool class="FallthruInSwitchStatement" enabled="true" level="WARNING" enabled_by_default="true" /> - <inspection_tool class="ForCanBeForeach" enabled="false" level="WARNING" enabled_by_default="false"> - <option name="REPORT_INDEXED_LOOP" value="true" /> - </inspection_tool> - <inspection_tool class="IndexOfReplaceableByContains" enabled="true" level="WARNING" enabled_by_default="true" /> - <inspection_tool class="JUnitAbstractTestClassNamingConvention" enabled="true" level="WARNING" enabled_by_default="true"> - <option name="m_regex" value="[A-Z][A-Za-z\d]*TestCase" /> - <option name="m_minLength" value="12" /> - <option name="m_maxLength" value="64" /> - </inspection_tool> - <inspection_tool class="JUnitTestClassNamingConvention" enabled="true" level="WARNING" enabled_by_default="true"> - <option name="m_regex" value="[A-Z][A-Za-z\d]*Test" /> - <option name="m_minLength" value="8" /> - <option name="m_maxLength" value="64" /> - </inspection_tool> - <inspection_tool class="JavaDoc" enabled="true" level="INFO" enabled_by_default="true"> - <option name="TOP_LEVEL_CLASS_OPTIONS"> - <value> - <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" /> - <option name="REQUIRED_TAGS" value="" /> - </value> - </option> - <option name="INNER_CLASS_OPTIONS"> - <value> - <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" /> - <option name="REQUIRED_TAGS" value="" /> - </value> - </option> - <option name="METHOD_OPTIONS"> - <value> - <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" /> - <option name="REQUIRED_TAGS" value="@return@param@throws or @exception" /> - </value> - </option> - <option name="FIELD_OPTIONS"> - <value> - <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" /> - <option name="REQUIRED_TAGS" value="" /> - </value> - </option> - <option name="IGNORE_DEPRECATED" value="false" /> - <option name="IGNORE_JAVADOC_PERIOD" value="true" /> - <option name="IGNORE_DUPLICATED_THROWS" value="false" /> - <option name="IGNORE_POINT_TO_ITSELF" value="false" /> - <option name="myAdditionalJavadocTags" value="" /> - </inspection_tool> - <inspection_tool class="JavadocReference" enabled="true" level="INFO" enabled_by_default="true" /> - <inspection_tool class="JpaDataSourceORMInspection" enabled="false" level="ERROR" enabled_by_default="false" /> - <inspection_tool class="MisorderedAssertEqualsParameters" enabled="true" level="WARNING" enabled_by_default="true" /> - <inspection_tool class="MissingDeprecatedAnnotation" enabled="true" level="WARNING" enabled_by_default="true" /> - <inspection_tool class="MissingOverrideAnnotation" enabled="true" level="WARNING" enabled_by_default="true"> - <option name="ignoreObjectMethods" value="true" /> - </inspection_tool> - <inspection_tool class="ProtectedField" enabled="true" level="WARNING" enabled_by_default="true" /> - <inspection_tool class="PublicConstructorInNonPublicClass" enabled="true" level="WARNING" enabled_by_default="true" /> - <inspection_tool class="PublicField" enabled="true" level="WARNING" enabled_by_default="true"> - <option name="ignoreEnums" value="false" /> - </inspection_tool> - <inspection_tool class="RedundantImplements" enabled="true" level="WARNING" enabled_by_default="true"> - <option name="ignoreSerializable" value="false" /> - <option name="ignoreCloneable" value="false" /> - </inspection_tool> - <inspection_tool class="SimplifiableIfStatement" enabled="false" level="WARNING" enabled_by_default="false" /> - <inspection_tool class="StaticSuite" enabled="true" level="WARNING" enabled_by_default="true" /> - <inspection_tool class="SystemOutErr" enabled="true" level="WARNING" enabled_by_default="true" /> - <inspection_tool class="TextLabelInSwitchStatement" enabled="true" level="WARNING" enabled_by_default="true" /> - <inspection_tool class="TodoComment" enabled="true" level="WARNING" enabled_by_default="true" /> - <inspection_tool class="TooBroadScope" enabled="true" level="WARNING" enabled_by_default="true"> - <option name="m_allowConstructorAsInitializer" value="false" /> - <option name="m_onlyLookAtBlocks" value="false" /> - </inspection_tool> - <inspection_tool class="UnnecessaryInterfaceModifier" enabled="true" level="WARNING" enabled_by_default="true" /> - <inspection_tool class="UtilityClassWithPublicConstructor" enabled="true" level="WARNING" enabled_by_default="true" /> - </profile> - </profiles> - <option name="PROJECT_PROFILE" value="Project Default" /> - <option name="USE_PROJECT_PROFILE" value="true" /> - <version value="1.0" /> - </component> - <component name="IssueNavigationConfiguration"> - <option name="links"> - <list> - <IssueNavigationLink> - <option name="issueRegexp" value="[A-Z]+\-\d+" /> - <option name="linkRegexp" value="http://jira.springframework.org/browse/$0" /> - </IssueNavigationLink> - </list> - </option> - </component> - <component name="JavadocGenerationManager"> - <option name="OUTPUT_DIRECTORY" /> - <option name="OPTION_SCOPE" value="protected" /> - <option name="OPTION_HIERARCHY" value="true" /> - <option name="OPTION_NAVIGATOR" value="true" /> - <option name="OPTION_INDEX" value="true" /> - <option name="OPTION_SEPARATE_INDEX" value="true" /> - <option name="OPTION_DOCUMENT_TAG_USE" value="false" /> - <option name="OPTION_DOCUMENT_TAG_AUTHOR" value="false" /> - <option name="OPTION_DOCUMENT_TAG_VERSION" value="false" /> - <option name="OPTION_DOCUMENT_TAG_DEPRECATED" value="true" /> - <option name="OPTION_DEPRECATED_LIST" value="true" /> - <option name="OTHER_OPTIONS" value="" /> - <option name="HEAP_SIZE" /> - <option name="LOCALE" /> - <option name="OPEN_IN_BROWSER" value="true" /> - </component> - <component name="LogConsolePreferences"> - <option name="FILTER_ERRORS" value="false" /> - <option name="FILTER_WARNINGS" value="false" /> - <option name="FILTER_INFO" value="true" /> - <option name="CUSTOM_FILTER" /> - </component> - <component name="MavenBuilder"> - <option name="jreName" value="1.4" /> - <option name="runMavenInBackground" value="true" /> - </component> - <component name="Palette2"> - <group name="Swing"> - <item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false"> - <default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" /> - </item> - <item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false"> - <default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" /> - </item> - <item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false"> - <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" /> - </item> - <item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true"> - <default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" /> - </item> - <item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false"> - <default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" /> - <initial-values> - <property name="text" value="Button" /> - </initial-values> - </item> - <item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false"> - <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" /> - <initial-values> - <property name="text" value="RadioButton" /> - </initial-values> - </item> - <item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false"> - <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" /> - <initial-values> - <property name="text" value="CheckBox" /> - </initial-values> - </item> - <item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false"> - <default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" /> - <initial-values> - <property name="text" value="Label" /> - </initial-values> - </item> - <item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true"> - <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1"> - <preferred-size width="150" height="-1" /> - </default-constraints> - </item> - <item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true"> - <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1"> - <preferred-size width="150" height="-1" /> - </default-constraints> - </item> - <item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true"> - <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1"> - <preferred-size width="150" height="-1" /> - </default-constraints> - </item> - <item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true"> - <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> - <preferred-size width="150" height="50" /> - </default-constraints> - </item> - <item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true"> - <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> - <preferred-size width="150" height="50" /> - </default-constraints> - </item> - <item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true"> - <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> - <preferred-size width="150" height="50" /> - </default-constraints> - </item> - <item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true"> - <default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" /> - </item> - <item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false"> - <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> - <preferred-size width="150" height="50" /> - </default-constraints> - </item> - <item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false"> - <default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3"> - <preferred-size width="150" height="50" /> - </default-constraints> - </item> - <item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false"> - <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> - <preferred-size width="150" height="50" /> - </default-constraints> - </item> - <item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false"> - <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3"> - <preferred-size width="200" height="200" /> - </default-constraints> - </item> - <item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false"> - <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3"> - <preferred-size width="200" height="200" /> - </default-constraints> - </item> - <item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true"> - <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" /> - </item> - <item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false"> - <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" /> - </item> - <item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false"> - <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" /> - </item> - <item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false"> - <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" /> - </item> - <item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false"> - <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1"> - <preferred-size width="-1" height="20" /> - </default-constraints> - </item> - <item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false"> - <default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" /> - </item> - <item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false"> - <default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" /> - </item> - </group> - </component> - <component name="ProjectDetails"> - <option name="projectName" value="spring-framework" /> - </component> - <component name="ProjectKey"> - <option name="state" value="https://src.springframework.org/svn/spring-framework/trunk/spring-framework.ipr" /> - </component> - <component name="ProjectModuleManager"> - <modules> - <module fileurl="file://$PROJECT_DIR$/org.springframework.aop/aop.iml" filepath="$PROJECT_DIR$/org.springframework.aop/aop.iml" /> - <module fileurl="file://$PROJECT_DIR$/org.springframework.beans/beans.iml" filepath="$PROJECT_DIR$/org.springframework.beans/beans.iml" /> - <module fileurl="file://$PROJECT_DIR$/build-spring-framework/build.iml" filepath="$PROJECT_DIR$/build-spring-framework/build.iml" /> - <module fileurl="file://$PROJECT_DIR$/org.springframework.context/context.iml" filepath="$PROJECT_DIR$/org.springframework.context/context.iml" /> - <module fileurl="file://$PROJECT_DIR$/org.springframework.context.support/context-support.iml" filepath="$PROJECT_DIR$/org.springframework.context.support/context-support.iml" /> - <module fileurl="file://$PROJECT_DIR$/org.springframework.core/core.iml" filepath="$PROJECT_DIR$/org.springframework.core/core.iml" /> - <module fileurl="file://$PROJECT_DIR$/org.springframework.expression/expression.iml" filepath="$PROJECT_DIR$/org.springframework.expression/expression.iml" /> - <module fileurl="file://$PROJECT_DIR$/org.springframework.instrument/instrument.iml" filepath="$PROJECT_DIR$/org.springframework.instrument/instrument.iml" /> - <module fileurl="file://$PROJECT_DIR$/org.springframework.integration-tests/integration-tests.iml" filepath="$PROJECT_DIR$/org.springframework.integration-tests/integration-tests.iml" /> - <module fileurl="file://$PROJECT_DIR$/org.springframework.jdbc/jdbc.iml" filepath="$PROJECT_DIR$/org.springframework.jdbc/jdbc.iml" /> - <module fileurl="file://$PROJECT_DIR$/org.springframework.jms/jms.iml" filepath="$PROJECT_DIR$/org.springframework.jms/jms.iml" /> - <module fileurl="file://$PROJECT_DIR$/org.springframework.orm/orm.iml" filepath="$PROJECT_DIR$/org.springframework.orm/orm.iml" /> - <module fileurl="file://$PROJECT_DIR$/org.springframework.oxm/oxm.iml" filepath="$PROJECT_DIR$/org.springframework.oxm/oxm.iml" /> - <module fileurl="file://$PROJECT_DIR$/org.springframework.test/test.iml" filepath="$PROJECT_DIR$/org.springframework.test/test.iml" /> - <module fileurl="file://$PROJECT_DIR$/org.springframework.transaction/transaction.iml" filepath="$PROJECT_DIR$/org.springframework.transaction/transaction.iml" /> - <module fileurl="file://$PROJECT_DIR$/org.springframework.web/web.iml" filepath="$PROJECT_DIR$/org.springframework.web/web.iml" /> - <module fileurl="file://$PROJECT_DIR$/org.springframework.web.portlet/web-portlet.iml" filepath="$PROJECT_DIR$/org.springframework.web.portlet/web-portlet.iml" /> - <module fileurl="file://$PROJECT_DIR$/org.springframework.web.servlet/web-servlet.iml" filepath="$PROJECT_DIR$/org.springframework.web.servlet/web-servlet.iml" /> - </modules> - </component> - <component name="ProjectResources"> - <default-html-doctype>http://www.w3.org/1999/xhtml</default-html-doctype> - </component> - <component name="ProjectRootManager" version="2" languageLevel="JDK_1_5" assert-keyword="true" jdk-15="true" project-jdk-name="1.6" project-jdk-type="JavaSDK"> - <output url="file://$PROJECT_DIR$/target" /> - </component> - <component name="ResourceManagerContainer"> - <option name="myResourceBundles"> - <value> - <list size="0" /> - </value> - </option> - </component> - <component name="SvnBranchConfigurationManager"> - <option name="myConfigurationMap"> - <map> - <entry key="$PROJECT_DIR$"> - <value> - <SvnBranchConfiguration> - <option name="branchMap"> - <map> - <entry key="https://src.springframework.org/svn/spring-framework/branches"> - <value> - <list> - <SvnBranchItem> - <option name="creationDateMillis" value="1307539501770" /> - <option name="revision" value="4492" /> - <option name="url" value="https://src.springframework.org/svn/spring-framework/branches/3.0.x" /> - </SvnBranchItem> - <SvnBranchItem> - <option name="creationDateMillis" value="1302041697740" /> - <option name="revision" value="4183" /> - <option name="url" value="https://src.springframework.org/svn/spring-framework/branches/mvc2" /> - </SvnBranchItem> - <SvnBranchItem> - <option name="creationDateMillis" value="1300966623519" /> - <option name="revision" value="4113" /> - <option name="url" value="https://src.springframework.org/svn/spring-framework/branches/conversation" /> - </SvnBranchItem> - <SvnBranchItem> - <option name="creationDateMillis" value="1291221081380" /> - <option name="revision" value="3805" /> - <option name="url" value="https://src.springframework.org/svn/spring-framework/branches/refresh" /> - </SvnBranchItem> - <SvnBranchItem> - <option name="creationDateMillis" value="1284379954359" /> - <option name="revision" value="3678" /> - <option name="url" value="https://src.springframework.org/svn/spring-framework/branches/next" /> - </SvnBranchItem> - <SvnBranchItem> - <option name="creationDateMillis" value="1271976232439" /> - <option name="revision" value="3295" /> - <option name="url" value="https://src.springframework.org/svn/spring-framework/branches/beanbuilder" /> - </SvnBranchItem> - <SvnBranchItem> - <option name="creationDateMillis" value="1271587525029" /> - <option name="revision" value="3262" /> - <option name="url" value="https://src.springframework.org/svn/spring-framework/branches/environment" /> - </SvnBranchItem> - <SvnBranchItem> - <option name="creationDateMillis" value="1251649548863" /> - <option name="revision" value="1789" /> - <option name="url" value="https://src.springframework.org/svn/spring-framework/branches/presentation-model" /> - </SvnBranchItem> - <SvnBranchItem> - <option name="creationDateMillis" value="1249330304955" /> - <option name="revision" value="1677" /> - <option name="url" value="https://src.springframework.org/svn/spring-framework/branches/binding" /> - </SvnBranchItem> - </list> - </value> - </entry> - <entry key="https://src.springframework.org/svn/spring-framework/tags"> - <value> - <list> - <SvnBranchItem> - <option name="creationDateMillis" value="1297412550536" /> - <option name="revision" value="3998" /> - <option name="url" value="https://src.springframework.org/svn/spring-framework/tags/spring-framework-3.1.0.M1" /> - </SvnBranchItem> - <SvnBranchItem> - <option name="creationDateMillis" value="1287617582380" /> - <option name="revision" value="3781" /> - <option name="url" value="https://src.springframework.org/svn/spring-framework/tags/spring-framework-3.0.5.RELEASE" /> - </SvnBranchItem> - <SvnBranchItem> - <option name="creationDateMillis" value="1282215059058" /> - <option name="revision" value="3609" /> - <option name="url" value="https://src.springframework.org/svn/spring-framework/tags/spring-framework-3.0.4.RELEASE" /> - </SvnBranchItem> - <SvnBranchItem> - <option name="creationDateMillis" value="1276611301169" /> - <option name="revision" value="3427" /> - <option name="url" value="https://src.springframework.org/svn/spring-framework/tags/spring-framework-3.0.3.RELEASE" /> - </SvnBranchItem> - <SvnBranchItem> - <option name="creationDateMillis" value="1270204619287" /> - <option name="revision" value="3225" /> - <option name="url" value="https://src.springframework.org/svn/spring-framework/tags/spring-framework-3.0.2.RELEASE" /> - </SvnBranchItem> - <SvnBranchItem> - <option name="creationDateMillis" value="1266579667903" /> - <option name="revision" value="3016" /> - <option name="url" value="https://src.springframework.org/svn/spring-framework/tags/spring-framework-3.0.1.RELEASE-A" /> - </SvnBranchItem> - <SvnBranchItem> - <option name="creationDateMillis" value="1266515819404" /> - <option name="revision" value="3011" /> - <option name="url" value="https://src.springframework.org/svn/spring-framework/tags/spring-framework-3.0.1.RELEASE" /> - </SvnBranchItem> - <SvnBranchItem> - <option name="creationDateMillis" value="1260982619585" /> - <option name="revision" value="2690" /> - <option name="url" value="https://src.springframework.org/svn/spring-framework/tags/spring-framework-3.0.0.RELEASE" /> - </SvnBranchItem> - <SvnBranchItem> - <option name="creationDateMillis" value="1259677464512" /> - <option name="revision" value="2559" /> - <option name="url" value="https://src.springframework.org/svn/spring-framework/tags/spring-framework-3.0.0.RC3" /> - </SvnBranchItem> - <SvnBranchItem> - <option name="creationDateMillis" value="1258125187044" /> - <option name="revision" value="2429" /> - <option name="url" value="https://src.springframework.org/svn/spring-framework/tags/spring-framework-3.0.0.RC2" /> - </SvnBranchItem> - <SvnBranchItem> - <option name="creationDateMillis" value="1254128397814" /> - <option name="revision" value="2027" /> - <option name="url" value="https://src.springframework.org/svn/spring-framework/tags/spring-framework-3.0.0.RC1" /> - </SvnBranchItem> - <SvnBranchItem> - <option name="creationDateMillis" value="1249899441422" /> - <option name="revision" value="1728" /> - <option name="url" value="https://src.springframework.org/svn/spring-framework/tags/spring-framework-3.0.0.M4" /> - </SvnBranchItem> - <SvnBranchItem> - <option name="creationDateMillis" value="1241614845476" /> - <option name="revision" value="1123" /> - <option name="url" value="https://src.springframework.org/svn/spring-framework/tags/spring-framework-3.0.0.M3" /> - </SvnBranchItem> - <SvnBranchItem> - <option name="creationDateMillis" value="1235589064654" /> - <option name="revision" value="699" /> - <option name="url" value="https://src.springframework.org/svn/spring-framework/tags/spring-framework-3.0.0.M2" /> - </SvnBranchItem> - <SvnBranchItem> - <option name="creationDateMillis" value="1229708575981" /> - <option name="revision" value="483" /> - <option name="url" value="https://src.springframework.org/svn/spring-framework/tags/spring-framework-3.0.0.M1" /> - </SvnBranchItem> - </list> - </value> - </entry> - </map> - </option> - <option name="branchUrls"> - <list> - <option value="https://src.springframework.org/svn/spring-framework/branches" /> - <option value="https://src.springframework.org/svn/spring-framework/tags" /> - </list> - </option> - <option name="trunkUrl" value="https://src.springframework.org/svn/spring-framework/trunk" /> - </SvnBranchConfiguration> - </value> - </entry> - <entry key="$PROJECT_DIR$/org.springframework.web.servlet"> - <value> - <SvnBranchConfiguration> - <option name="branchMap"> - <map> - <entry key="https://src.springframework.org/svn/spring-framework/branches"> - <value> - <list /> - </value> - </entry> - <entry key="https://src.springframework.org/svn/spring-framework/tags"> - <value> - <list /> - </value> - </entry> - </map> - </option> - <option name="branchUrls"> - <list> - <option value="https://src.springframework.org/svn/spring-framework/branches" /> - <option value="https://src.springframework.org/svn/spring-framework/tags" /> - </list> - </option> - <option name="trunkUrl" value="https://src.springframework.org/svn/spring-framework/trunk" /> - </SvnBranchConfiguration> - </value> - </entry> - <entry key="$PROJECT_DIR$/spring-build"> - <value> - <SvnBranchConfiguration> - <option name="branchMap"> - <map> - <entry key="https://src.springsource.org/svn/spring-build/branches"> - <value> - <list /> - </value> - </entry> - <entry key="https://src.springsource.org/svn/spring-build/tags"> - <value> - <list /> - </value> - </entry> - </map> - </option> - <option name="branchUrls"> - <list> - <option value="https://src.springsource.org/svn/spring-build/branches" /> - <option value="https://src.springsource.org/svn/spring-build/tags" /> - </list> - </option> - <option name="trunkUrl" value="https://src.springsource.org/svn/spring-build/trunk" /> - </SvnBranchConfiguration> - </value> - </entry> - </map> - </option> - <option name="myVersion" value="124" /> - <option name="mySupportsUserInfoFilter" value="true" /> - </component> - <component name="SvnChangesBrowserSettings"> - <option name="USE_AUTHOR_FIELD" value="true" /> - <option name="AUTHOR" value="" /> - <option name="LOCATION" value="" /> - <option name="USE_PROJECT_SETTINGS" value="true" /> - <option name="USE_ALTERNATE_LOCATION" value="false" /> - </component> - <component name="ThePluginSettings"> - <option name="bambooConfiguration"> - <BambooProjectConfiguration> - <option name="tableConfiguration"> - <ProjectToolWindowTableConfiguration /> - </option> - </BambooProjectConfiguration> - </option> - <option name="crucibleConfiguration"> - <CrucibleProjectConfiguration> - <option name="crucibleFilters"> - <CrucibleFiltersBean /> - </option> - <option name="tableConfiguration"> - <ProjectToolWindowTableConfiguration /> - </option> - </CrucibleProjectConfiguration> - </option> - <option name="jiraConfiguration"> - <JiraProjectConfiguration> - <option name="tableConfiguration"> - <ProjectToolWindowTableConfiguration /> - </option> - </JiraProjectConfiguration> - </option> - </component> - <component name="VCS.FileViewConfiguration"> - <option name="SELECTED_STATUSES" value="DEFAULT" /> - <option name="SELECTED_COLUMNS" value="DEFAULT" /> - <option name="SHOW_FILTERS" value="true" /> - <option name="CUSTOMIZE_VIEW" value="true" /> - <option name="SHOW_FILE_HISTORY_AS_TREE" value="true" /> - </component> - <component name="VcsDirectoryMappings"> - <mapping directory="" vcs="svn" /> - </component> - <component name="WebServicesPlugin" addRequiredLibraries="true" /> - <component name="com.intellij.ide.util.scopeChooser.ScopeChooserConfigurable" proportions="" version="1"> - <option name="myLastEditedConfigurable" /> - </component> - <component name="com.intellij.jsf.UserDefinedFacesConfigs"> - <option name="USER_DEFINED_CONFIGS"> - <value> - <list size="0" /> - </value> - </option> - </component> - <component name="com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectRootMasterDetailsConfigurable" proportions="" version="1"> - <option name="myPlainMode" value="false" /> - <option name="myLastEditedConfigurable" /> - </component> - <component name="com.intellij.profile.ui.ErrorOptionsConfigurable" proportions="" version="1"> - <option name="myLastEditedConfigurable" /> - </component> - <component name="copyright"> - <Base> - <setting name="state" value="2" /> - </Base> - </component> - <component name="libraryTable"> - <library name="AOP Alliance"> - <CLASSES> - <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.aopalliance/com.springsource.org.aopalliance/1.0.0/com.springsource.org.aopalliance-1.0.0.jar!/" /> - </CLASSES> - <JAVADOC /> - <SOURCES> - <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.aopalliance/com.springsource.org.aopalliance/1.0.0/com.springsource.org.aopalliance-sources-1.0.0.jar!/" /> - </SOURCES> - </library> - <library name="ASM"> - <CLASSES> - <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.objectweb.asm/com.springsource.org.objectweb.asm/2.2.3/com.springsource.org.objectweb.asm-2.2.3.jar!/" /> - <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.objectweb.asm/com.springsource.org.objectweb.asm.commons/2.2.3/com.springsource.org.objectweb.asm.commons-2.2.3.jar!/" /> - </CLASSES> - <JAVADOC /> - <SOURCES> - <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.objectweb.asm/com.springsource.org.objectweb.asm/2.2.3/com.springsource.org.objectweb.asm-sources-2.2.3.jar!/" /> - <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.objectweb.asm/com.springsource.org.objectweb.asm.commons/2.2.3/com.springsource.org.objectweb.asm.commons-sources-2.2.3.jar!/" /> - </SOURCES> - </library> - <library name="AspectJ"> - <CLASSES> - <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.aspectj/com.springsource.org.aspectj.weaver/1.6.8.RELEASE/com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar!/" /> - </CLASSES> - <JAVADOC /> - <SOURCES> - <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.aspectj/com.springsource.org.aspectj.weaver/1.6.8.RELEASE/com.springsource.org.aspectj.weaver-sources-1.6.8.RELEASE.jar!/" /> - </SOURCES> - </library> - <library name="CGLIB"> - <CLASSES> - <root url="jar://$PROJECT_DIR$/ivy-cache/repository/net.sourceforge.cglib/com.springsource.net.sf.cglib/2.2.0/com.springsource.net.sf.cglib-2.2.0.jar!/" /> - </CLASSES> - <JAVADOC /> - <SOURCES> - <root url="jar://$PROJECT_DIR$/ivy-cache/repository/net.sourceforge.cglib/com.springsource.net.sf.cglib/2.2.0/com.springsource.net.sf.cglib-sources-2.2.0.jar!/" /> - </SOURCES> - </library> - <library name="Commons Collections"> - <CLASSES> - <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.apache.commons/com.springsource.org.apache.commons.collections/3.2.0/com.springsource.org.apache.commons.collections-3.2.0.jar!/" /> - </CLASSES> - <JAVADOC /> - <SOURCES> - <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.apache.commons/com.springsource.org.apache.commons.collections/3.2.0/com.springsource.org.apache.commons.collections-sources-3.2.0.jar!/" /> - </SOURCES> - </library> - <library name="Commons Logging"> - <CLASSES> - <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.apache.commons/com.springsource.org.apache.commons.logging/1.1.1/com.springsource.org.apache.commons.logging-1.1.1.jar!/" /> - </CLASSES> - <JAVADOC /> - <SOURCES> - <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.apache.commons/com.springsource.org.apache.commons.logging/1.1.1/com.springsource.org.apache.commons.logging-sources-1.1.1.jar!/" /> - </SOURCES> - </library> - <library name="Commons Pool"> - <CLASSES> - <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.apache.commons/com.springsource.org.apache.commons.pool/1.5.3/com.springsource.org.apache.commons.pool-1.5.3.jar!/" /> - </CLASSES> - <JAVADOC /> - <SOURCES> - <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.apache.commons/com.springsource.org.apache.commons.pool/1.5.3/com.springsource.org.apache.commons.pool-sources-1.5.3.jar!/" /> - </SOURCES> - </library> - <library name="EasyMock"> - <CLASSES> - <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.easymock/com.springsource.org.easymock/2.5.1/com.springsource.org.easymock-2.5.1.jar!/" /> - </CLASSES> - <JAVADOC /> - <SOURCES> - <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.easymock/com.springsource.org.easymock/2.5.1/com.springsource.org.easymock-sources-2.5.1.jar!/" /> - </SOURCES> - </library> - <library name="Hamcrest"> - <CLASSES> - <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.hamcrest/com.springsource.org.hamcrest/1.1.0/com.springsource.org.hamcrest-1.1.0.jar!/" /> - </CLASSES> - <JAVADOC /> - <SOURCES> - <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.hamcrest/com.springsource.org.hamcrest/1.1.0/com.springsource.org.hamcrest-sources-1.1.0.jar!/" /> - </SOURCES> - </library> - <library name="Jamon"> - <CLASSES> - <root url="jar://$PROJECT_DIR$/ivy-cache/repository/com.jamonapi/com.springsource.com.jamonapi/2.4.0/com.springsource.com.jamonapi-2.4.0.jar!/" /> - </CLASSES> - <JAVADOC /> - <SOURCES> - <root url="jar://$PROJECT_DIR$/ivy-cache/repository/com.jamonapi/com.springsource.com.jamonapi/2.4.0/com.springsource.com.jamonapi-sources-2.4.0.jar!/" /> - </SOURCES> - </library> - <library name="javax.el"> - <CLASSES> - <root url="jar://$PROJECT_DIR$/ivy-cache/repository/javax.el/com.springsource.javax.el/1.0.0/com.springsource.javax.el-1.0.0.jar!/" /> - </CLASSES> - <JAVADOC /> - <SOURCES> - <root url="jar://$PROJECT_DIR$/ivy-cache/repository/javax.el/com.springsource.javax.el/1.0.0/com.springsource.javax.el-sources-1.0.0.jar!/" /> - </SOURCES> - </library> - <library name="javax.inject"> - <CLASSES> - <root url="jar://$PROJECT_DIR$/ivy-cache/repository/javax.inject/com.springsource.javax.inject/1.0.0/com.springsource.javax.inject-1.0.0.jar!/" /> - </CLASSES> - <JAVADOC /> - <SOURCES> - <root url="jar://$PROJECT_DIR$/ivy-cache/repository/javax.inject/com.springsource.javax.inject/1.0.0/com.springsource.javax.inject-sources-1.0.0.jar!/" /> - </SOURCES> - </library> - <library name="javax.validation"> - <CLASSES> - <root url="jar://$PROJECT_DIR$/ivy-cache/repository/javax.validation/com.springsource.javax.validation/1.0.0.GA/com.springsource.javax.validation-1.0.0.GA.jar!/" /> - </CLASSES> - <JAVADOC /> - <SOURCES> - <root url="jar://$PROJECT_DIR$/ivy-cache/repository/javax.validation/com.springsource.javax.validation/1.0.0.GA/com.springsource.javax.validation-sources-1.0.0.GA.jar!/" /> - </SOURCES> - </library> - <library name="JUnit"> - <CLASSES> - <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.junit/com.springsource.org.junit/4.8.1/com.springsource.org.junit-4.8.1.jar!/" /> - </CLASSES> - <JAVADOC /> - <SOURCES> - <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.junit/com.springsource.org.junit/4.8.1/com.springsource.org.junit-sources-4.8.1.jar!/" /> - </SOURCES> - </library> - <library name="Log4j"> - <CLASSES> - <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.apache.log4j/com.springsource.org.apache.log4j/1.2.15/com.springsource.org.apache.log4j-1.2.15.jar!/" /> - </CLASSES> - <JAVADOC /> - <SOURCES> - <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.apache.log4j/com.springsource.org.apache.log4j/1.2.15/com.springsource.org.apache.log4j-sources-1.2.15.jar!/" /> - </SOURCES> - </library> - <library name="SLF4j"> - <CLASSES> - <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.slf4j/com.springsource.slf4j.api/1.5.3/com.springsource.slf4j.api-1.5.3.jar!/" /> - <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.slf4j/com.springsource.slf4j.jcl/1.5.3/com.springsource.slf4j.jcl-1.5.3.jar!/" /> - </CLASSES> - <JAVADOC /> - <SOURCES> - <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.slf4j/com.springsource.slf4j.api/1.5.3/com.springsource.slf4j.api-sources-1.5.3.jar!/" /> - <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.slf4j/com.springsource.slf4j.jcl/1.5.3/com.springsource.slf4j.jcl-sources-1.5.3.jar!/" /> - </SOURCES> - </library> - </component> -</project> - +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="AntConfiguration"> + <defaultAnt bundledAnt="true" /> + </component> + <component name="BuildJarProjectSettings"> + <option name="BUILD_JARS_ON_MAKE" value="false" /> + </component> + <component name="ChangeBrowserSettings"> + <option name="MAIN_SPLITTER_PROPORTION" value="0.3" /> + <option name="MESSAGES_SPLITTER_PROPORTION" value="0.8" /> + <option name="USE_DATE_BEFORE_FILTER" value="false" /> + <option name="USE_DATE_AFTER_FILTER" value="false" /> + <option name="USE_CHANGE_BEFORE_FILTER" value="false" /> + <option name="USE_CHANGE_AFTER_FILTER" value="false" /> + <option name="DATE_BEFORE" value="" /> + <option name="DATE_AFTER" value="" /> + <option name="CHANGE_BEFORE" value="" /> + <option name="CHANGE_AFTER" value="" /> + <option name="USE_USER_FILTER" value="false" /> + <option name="USER" value="" /> + </component> + <component name="CodeStyleProjectProfileManger"> + <option name="PROJECT_PROFILE" /> + <option name="USE_PROJECT_LEVEL_SETTINGS" value="false" /> + </component> + <component name="CodeStyleSettingsManager"> + <option name="PER_PROJECT_SETTINGS"> + <value> + <option name="JAVA_INDENT_OPTIONS"> + <value> + <option name="INDENT_SIZE" value="4" /> + <option name="CONTINUATION_INDENT_SIZE" value="8" /> + <option name="TAB_SIZE" value="4" /> + <option name="USE_TAB_CHARACTER" value="true" /> + <option name="SMART_TABS" value="false" /> + <option name="LABEL_INDENT_SIZE" value="0" /> + <option name="LABEL_INDENT_ABSOLUTE" value="false" /> + <option name="USE_RELATIVE_INDENTS" value="false" /> + </value> + </option> + <option name="LINE_SEPARATOR" value=" " /> + <option name="PREFER_LONGER_NAMES" value="false" /> + <option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999" /> + <option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="1" /> + <option name="IMPORT_LAYOUT_TABLE"> + <value> + <package name="java" withSubpackages="true" static="false" /> + <package name="javax" withSubpackages="true" static="false" /> + <emptyLine /> + <package name="" withSubpackages="true" static="false" /> + <emptyLine /> + <package name="org.springframework" withSubpackages="true" static="false" /> + <emptyLine /> + <package name="" withSubpackages="true" static="true" /> + </value> + </option> + <option name="JD_ALIGN_PARAM_COMMENTS" value="false" /> + <option name="JD_ALIGN_EXCEPTION_COMMENTS" value="false" /> + <option name="JD_P_AT_EMPTY_LINES" value="false" /> + <option name="JD_DO_NOT_WRAP_ONE_LINE_COMMENTS" value="true" /> + <option name="JD_KEEP_EMPTY_PARAMETER" value="false" /> + <option name="JD_KEEP_EMPTY_EXCEPTION" value="false" /> + <option name="JD_KEEP_EMPTY_RETURN" value="false" /> + <option name="XML_KEEP_WHITESPACES" value="true" /> + <option name="XML_TEXT_WRAP" value="0" /> + <option name="KEEP_LINE_BREAKS" value="false" /> + <option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1" /> + <option name="KEEP_BLANK_LINES_IN_CODE" value="1" /> + <option name="BLANK_LINES_AROUND_FIELD" value="1" /> + <option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1" /> + <option name="ELSE_ON_NEW_LINE" value="true" /> + <option name="WHILE_ON_NEW_LINE" value="true" /> + <option name="CATCH_ON_NEW_LINE" value="true" /> + <option name="FINALLY_ON_NEW_LINE" value="true" /> + <option name="ALIGN_MULTILINE_PARAMETERS" value="false" /> + <option name="ALIGN_MULTILINE_FOR" value="false" /> + <option name="CALL_PARAMETERS_WRAP" value="1" /> + <option name="METHOD_PARAMETERS_WRAP" value="5" /> + <option name="EXTENDS_LIST_WRAP" value="1" /> + <option name="THROWS_LIST_WRAP" value="1" /> + <option name="EXTENDS_KEYWORD_WRAP" value="1" /> + <option name="THROWS_KEYWORD_WRAP" value="1" /> + <option name="METHOD_CALL_CHAIN_WRAP" value="1" /> + <option name="BINARY_OPERATION_WRAP" value="1" /> + <option name="TERNARY_OPERATION_WRAP" value="1" /> + <option name="FOR_STATEMENT_WRAP" value="5" /> + <option name="ARRAY_INITIALIZER_WRAP" value="1" /> + <option name="ASSIGNMENT_WRAP" value="1" /> + <option name="WRAP_COMMENTS" value="true" /> + <option name="IF_BRACE_FORCE" value="3" /> + <option name="DOWHILE_BRACE_FORCE" value="3" /> + <option name="WHILE_BRACE_FORCE" value="3" /> + <option name="FOR_BRACE_FORCE" value="3" /> + <ADDITIONAL_INDENT_OPTIONS fileType="groovy"> + <option name="INDENT_SIZE" value="2" /> + <option name="CONTINUATION_INDENT_SIZE" value="8" /> + <option name="TAB_SIZE" value="4" /> + <option name="USE_TAB_CHARACTER" value="false" /> + <option name="SMART_TABS" value="false" /> + <option name="LABEL_INDENT_SIZE" value="0" /> + <option name="LABEL_INDENT_ABSOLUTE" value="false" /> + <option name="USE_RELATIVE_INDENTS" value="false" /> + </ADDITIONAL_INDENT_OPTIONS> + <ADDITIONAL_INDENT_OPTIONS fileType="gsp"> + <option name="INDENT_SIZE" value="2" /> + <option name="CONTINUATION_INDENT_SIZE" value="8" /> + <option name="TAB_SIZE" value="4" /> + <option name="USE_TAB_CHARACTER" value="false" /> + <option name="SMART_TABS" value="false" /> + <option name="LABEL_INDENT_SIZE" value="0" /> + <option name="LABEL_INDENT_ABSOLUTE" value="false" /> + <option name="USE_RELATIVE_INDENTS" value="false" /> + </ADDITIONAL_INDENT_OPTIONS> + <ADDITIONAL_INDENT_OPTIONS fileType="java"> + <option name="INDENT_SIZE" value="4" /> + <option name="CONTINUATION_INDENT_SIZE" value="8" /> + <option name="TAB_SIZE" value="4" /> + <option name="USE_TAB_CHARACTER" value="true" /> + <option name="SMART_TABS" value="false" /> + <option name="LABEL_INDENT_SIZE" value="0" /> + <option name="LABEL_INDENT_ABSOLUTE" value="false" /> + <option name="USE_RELATIVE_INDENTS" value="false" /> + </ADDITIONAL_INDENT_OPTIONS> + <ADDITIONAL_INDENT_OPTIONS fileType="js"> + <option name="INDENT_SIZE" value="4" /> + <option name="CONTINUATION_INDENT_SIZE" value="8" /> + <option name="TAB_SIZE" value="4" /> + <option name="USE_TAB_CHARACTER" value="false" /> + <option name="SMART_TABS" value="false" /> + <option name="LABEL_INDENT_SIZE" value="0" /> + <option name="LABEL_INDENT_ABSOLUTE" value="false" /> + <option name="USE_RELATIVE_INDENTS" value="false" /> + </ADDITIONAL_INDENT_OPTIONS> + <ADDITIONAL_INDENT_OPTIONS fileType="jsp"> + <option name="INDENT_SIZE" value="4" /> + <option name="CONTINUATION_INDENT_SIZE" value="8" /> + <option name="TAB_SIZE" value="4" /> + <option name="USE_TAB_CHARACTER" value="false" /> + <option name="SMART_TABS" value="false" /> + <option name="LABEL_INDENT_SIZE" value="0" /> + <option name="LABEL_INDENT_ABSOLUTE" value="false" /> + <option name="USE_RELATIVE_INDENTS" value="false" /> + </ADDITIONAL_INDENT_OPTIONS> + <ADDITIONAL_INDENT_OPTIONS fileType="php"> + <option name="INDENT_SIZE" value="4" /> + <option name="CONTINUATION_INDENT_SIZE" value="8" /> + <option name="TAB_SIZE" value="4" /> + <option name="USE_TAB_CHARACTER" value="false" /> + <option name="SMART_TABS" value="false" /> + <option name="LABEL_INDENT_SIZE" value="0" /> + <option name="LABEL_INDENT_ABSOLUTE" value="false" /> + <option name="USE_RELATIVE_INDENTS" value="false" /> + </ADDITIONAL_INDENT_OPTIONS> + <ADDITIONAL_INDENT_OPTIONS fileType="sass"> + <option name="INDENT_SIZE" value="2" /> + <option name="CONTINUATION_INDENT_SIZE" value="8" /> + <option name="TAB_SIZE" value="4" /> + <option name="USE_TAB_CHARACTER" value="false" /> + <option name="SMART_TABS" value="false" /> + <option name="LABEL_INDENT_SIZE" value="0" /> + <option name="LABEL_INDENT_ABSOLUTE" value="false" /> + <option name="USE_RELATIVE_INDENTS" value="false" /> + </ADDITIONAL_INDENT_OPTIONS> + <ADDITIONAL_INDENT_OPTIONS fileType="sql"> + <option name="INDENT_SIZE" value="2" /> + <option name="CONTINUATION_INDENT_SIZE" value="8" /> + <option name="TAB_SIZE" value="4" /> + <option name="USE_TAB_CHARACTER" value="false" /> + <option name="SMART_TABS" value="false" /> + <option name="LABEL_INDENT_SIZE" value="0" /> + <option name="LABEL_INDENT_ABSOLUTE" value="false" /> + <option name="USE_RELATIVE_INDENTS" value="false" /> + </ADDITIONAL_INDENT_OPTIONS> + <ADDITIONAL_INDENT_OPTIONS fileType="txt"> + <option name="INDENT_SIZE" value="2" /> + <option name="CONTINUATION_INDENT_SIZE" value="8" /> + <option name="TAB_SIZE" value="4" /> + <option name="USE_TAB_CHARACTER" value="false" /> + <option name="SMART_TABS" value="false" /> + <option name="LABEL_INDENT_SIZE" value="0" /> + <option name="LABEL_INDENT_ABSOLUTE" value="false" /> + <option name="USE_RELATIVE_INDENTS" value="false" /> + </ADDITIONAL_INDENT_OPTIONS> + <ADDITIONAL_INDENT_OPTIONS fileType="xml"> + <option name="INDENT_SIZE" value="4" /> + <option name="CONTINUATION_INDENT_SIZE" value="8" /> + <option name="TAB_SIZE" value="4" /> + <option name="USE_TAB_CHARACTER" value="true" /> + <option name="SMART_TABS" value="false" /> + <option name="LABEL_INDENT_SIZE" value="0" /> + <option name="LABEL_INDENT_ABSOLUTE" value="false" /> + <option name="USE_RELATIVE_INDENTS" value="false" /> + </ADDITIONAL_INDENT_OPTIONS> + <ADDITIONAL_INDENT_OPTIONS fileType="yml"> + <option name="INDENT_SIZE" value="2" /> + <option name="CONTINUATION_INDENT_SIZE" value="8" /> + <option name="TAB_SIZE" value="4" /> + <option name="USE_TAB_CHARACTER" value="false" /> + <option name="SMART_TABS" value="false" /> + <option name="LABEL_INDENT_SIZE" value="0" /> + <option name="LABEL_INDENT_ABSOLUTE" value="false" /> + <option name="USE_RELATIVE_INDENTS" value="false" /> + </ADDITIONAL_INDENT_OPTIONS> + </value> + </option> + <option name="USE_PER_PROJECT_SETTINGS" value="true" /> + </component> + <component name="CompilerConfiguration"> + <option name="DEFAULT_COMPILER" value="Javac" /> + <resourceExtensions> + <entry name=".+\.(properties|xml|html|dtd|tld)" /> + <entry name=".+\.(gif|png|jpeg|jpg)" /> + </resourceExtensions> + <wildcardResourcePatterns> + <entry name="*.properties" /> + <entry name="*.txt" /> + <entry name="*.xml" /> + <entry name="*.gif" /> + <entry name="*.png" /> + <entry name="*.jpeg" /> + <entry name="*.jpg" /> + <entry name="*.html" /> + <entry name="*.css" /> + <entry name="*.js" /> + <entry name="*.dtd" /> + <entry name="*.xsd" /> + <entry name="*.tld" /> + <entry name="*.xls" /> + <entry name="*.vm" /> + <entry name="*.ftl" /> + <entry name="*.sql" /> + <entry name="*.types" /> + <entry name="*.bsh" /> + <entry name="*.rb" /> + <entry name="*.groovy" /> + <entry name="*.handlers" /> + <entry name="*.schemas" /> + </wildcardResourcePatterns> + <annotationProcessing enabled="false" useClasspath="true" /> + </component> + <component name="CopyrightManager" default="Spring"> + <copyright> + <option name="notice" value="Copyright 2002-&#36;today.year the original author or authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License." /> + <option name="keyword" value="Copyright" /> + <option name="allowReplaceKeyword" value="" /> + <option name="myName" value="Spring" /> + <option name="myLocal" value="true" /> + </copyright> + <module2copyright> + <element module="All" copyright="Spring" /> + </module2copyright> + <LanguageOptions name="HTML"> + <option name="fileTypeOverride" value="1" /> + </LanguageOptions> + <LanguageOptions name="JSP"> + <option name="fileTypeOverride" value="1" /> + </LanguageOptions> + <LanguageOptions name="JSPX"> + <option name="fileTypeOverride" value="1" /> + </LanguageOptions> + <LanguageOptions name="JavaScript"> + <option name="fileTypeOverride" value="1" /> + </LanguageOptions> + <LanguageOptions name="Properties"> + <option name="fileTypeOverride" value="1" /> + </LanguageOptions> + <LanguageOptions name="XML"> + <option name="fileTypeOverride" value="1" /> + </LanguageOptions> + </component> + <component name="DependenciesAnalyzeManager"> + <option name="myForwardDirection" value="false" /> + </component> + <component name="DependencyValidationManager"> + <option name="SKIP_IMPORT_STATEMENTS" value="false" /> + </component> + <component name="EclipseCompilerSettings"> + <option name="GENERATE_NO_WARNINGS" value="true" /> + </component> + <component name="EclipseEmbeddedCompilerSettings"> + <option name="DEBUGGING_INFO" value="true" /> + <option name="GENERATE_NO_WARNINGS" value="true" /> + <option name="DEPRECATION" value="false" /> + <option name="ADDITIONAL_OPTIONS_STRING" value="" /> + <option name="MAXIMUM_HEAP_SIZE" value="128" /> + </component> + <component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" /> + <component name="EntryPointsManager"> + <entry_points version="2.0" /> + </component> + <component name="ExportToHTMLSettings"> + <option name="PRINT_LINE_NUMBERS" value="false" /> + <option name="OPEN_IN_BROWSER" value="false" /> + <option name="OUTPUT_DIRECTORY" /> + </component> + <component name="FacetAutodetectingManager"> + <autodetection-disabled> + <facet-type id="Gant_Grails" /> + <facet-type id="Grails" /> + <facet-type id="Groovy" /> + <facet-type id="jpa"> + <modules> + <module name="integration-tests" /> + <module name="orm"> + <files> + <file url="file://$PROJECT_DIR$/org.springframework.orm/src/test/java/org/springframework/orm/jpa/META-INF/persistence.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.orm/src/test/java/org/springframework/orm/jpa/domain/persistence-context.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.orm/src/test/java/org/springframework/orm/jpa/domain/persistence-multi.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.orm/src/test/java/org/springframework/orm/jpa/domain/persistence.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.orm/src/test/java/org/springframework/orm/jpa/persistence-complex.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.orm/src/test/java/org/springframework/orm/jpa/persistence-example1.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.orm/src/test/java/org/springframework/orm/jpa/persistence-example2.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.orm/src/test/java/org/springframework/orm/jpa/persistence-example3.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.orm/src/test/java/org/springframework/orm/jpa/persistence-example4.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.orm/src/test/java/org/springframework/orm/jpa/persistence-example5.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.orm/src/test/java/org/springframework/orm/jpa/persistence-example6.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.orm/src/test/java/org/springframework/orm/jpa/persistence-invalid.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.orm/src/test/java/org/springframework/orm/jpa/persistence-no-schema.xml" /> + </files> + </module> + </modules> + </facet-type> + <facet-type id="Spring"> + <modules> + <module name="aop"> + <files> + <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/config/AopNamespaceHandlerEventTests-context.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/config/AopNamespaceHandlerEventTests-directPointcutEvents.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/config/AopNamespaceHandlerEventTests-pointcutEvents.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/config/AopNamespaceHandlerEventTests-pointcutRefEvents.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/config/AopNamespaceHandlerPointcutErrorTests-pointcutDuplication.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/config/AopNamespaceHandlerPointcutErrorTests-pointcutMissing.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/config/aopNamespaceHandlerAdvisorWithDirectPointcutEventTests.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/config/aopNamespaceHandlerAdvisorWithPointcutRefEventTests.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/config/aopNamespaceHandlerAspectEventTests.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/config/aopNamespaceHandlerPointcutDuplicationTests.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/config/aopNamespaceHandlerPointcutEventTests.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/config/aopNamespaceHandlerPointcutMissingTests.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/framework/PrototypeTargetTests-context.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/framework/prototypeTarget.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/interceptor/ExposeInvocationInterceptorTests-context.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/interceptor/exposeInvocation.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/scope/ScopedProxyAutowireTests-scopedAutowireFalse.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/scope/ScopedProxyAutowireTests-scopedAutowireTrue.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/scope/scopedAutowireFalse.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/scope/scopedAutowireTrue.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/support/RegexpMethodPointcutAdvisorIntegrationTests-context.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/support/regexpSetterTests.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/target/CommonsPoolTargetSourceProxyTests-context.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/target/HotSwappableTargetSourceTests-context.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/target/LazyInitTargetSourceTests-customTarget.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/target/LazyInitTargetSourceTests-factoryBean.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/target/LazyInitTargetSourceTests-singleton.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/target/PrototypeTargetSourceTests-context.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/target/ThreadLocalTargetSourceTests-context.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/target/commonsPoolProxyTests.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/target/customLazyInitTarget.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/target/hotSwapTests.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/target/lazyInitFactoryBean.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/target/lazyInitSingletonTests.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/target/prototypeTests.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.aop/src/test/java/org/springframework/aop/target/threadLocalTests.xml" /> + </files> + </module> + <module name="beans" /> + <module name="context" /> + <module name="context-support" /> + <module name="integration-tests" /> + <module name="jdbc" /> + <module name="jms" /> + <module name="org.springframework.integration-tests" /> + <module name="org.springframework.jdbc" /> + <module name="orm" /> + <module name="oxm"> + <files> + <file url="file://$PROJECT_DIR$/org.springframework.oxm/src/test/resources/org/springframework/oxm/config/oxmNamespaceHandlerTest.xml" /> + </files> + </module> + <module name="test" /> + <module name="transaction"> + <files> + <file url="file://$PROJECT_DIR$/org.springframework.transaction/src/test/java/org/springframework/transaction/annotation/annotationTransactionNamespaceHandlerTests.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.transaction/src/test/java/org/springframework/transaction/config/annotationDrivenProxyTargetClassTests.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.transaction/src/test/java/org/springframework/transaction/interceptor/noTransactionAttributeSource.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.transaction/src/test/java/org/springframework/transaction/interceptor/transactionalBeanFactory.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.transaction/src/test/java/org/springframework/transaction/txNamespaceHandlerTests.xml" /> + </files> + </module> + <module name="web"> + <files> + <file url="file://$PROJECT_DIR$/org.springframework.web/src/test/resources/org/springframework/web/context/request/requestScopeTests.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.web/src/test/resources/org/springframework/web/context/request/requestScopedProxyTests.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.web/src/test/resources/org/springframework/web/context/request/sessionScopeTests.xml" /> + </files> + </module> + <module name="web-portlet"> + <files> + <file url="file://$PROJECT_DIR$/org.springframework.web.portlet/src/test/java/org/springframework/web/portlet/context/WEB-INF/applicationContext.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.web.portlet/src/test/java/org/springframework/web/portlet/context/WEB-INF/empty-portlet.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.web.portlet/src/test/java/org/springframework/web/portlet/context/WEB-INF/resources/messageSource.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.web.portlet/src/test/java/org/springframework/web/portlet/context/WEB-INF/resources/themeSource.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.web.portlet/src/test/java/org/springframework/web/portlet/context/WEB-INF/test-portlet.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.web.portlet/src/test/java/org/springframework/web/portlet/context/WEB-INF/test-servlet.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.web.portlet/src/test/java/org/springframework/web/portlet/handler/parameterMapping.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.web.portlet/src/test/java/org/springframework/web/portlet/handler/portletModeMapping.xml" /> + <file url="file://$PROJECT_DIR$/org.springframework.web.portlet/src/test/java/org/springframework/web/portlet/handler/portletModeParameterMapping.xml" /> + </files> + </module> + <module name="web-servlet" /> + </modules> + </facet-type> + <facet-type id="web"> + <modules> + <module name="integration-tests" /> + <module name="org.springframework.integration-tests" /> + <module name="web-servlet"> + <files> + <file url="file://$PROJECT_DIR$/org.springframework.web.servlet/src/test/java/org/springframework/web/context/WEB-INF/web.xml" /> + </files> + </module> + </modules> + </facet-type> + </autodetection-disabled> + </component> + <component name="IdProvider" IDEtalkID="C2515F8F9A78051322E588EF85003B36" /> + <component name="InspectionProjectProfileManager"> + <profiles> + <profile version="1.0" is_locked="false"> + <option name="myName" value="Project Default" /> + <option name="myLocal" value="false" /> + <inspection_tool class="AssertsWithoutMessages" enabled="true" level="WARNING" enabled_by_default="true" /> + <inspection_tool class="ClassWithMultipleLoggers" enabled="true" level="WARNING" enabled_by_default="true"> + <option name="loggerNamesString" value="java.util.logging.Logger,org.slf4j.Logger,org.apache.commons.logging.Log,org.apache.log4j.Logger" /> + </inspection_tool> + <inspection_tool class="EqualsAndHashcode" enabled="true" level="WARNING" enabled_by_default="true" /> + <inspection_tool class="FallthruInSwitchStatement" enabled="true" level="WARNING" enabled_by_default="true" /> + <inspection_tool class="ForCanBeForeach" enabled="false" level="WARNING" enabled_by_default="false"> + <option name="REPORT_INDEXED_LOOP" value="true" /> + <option name="ignoreUntypedCollections" value="false" /> + </inspection_tool> + <inspection_tool class="JUnitAbstractTestClassNamingConvention" enabled="true" level="WARNING" enabled_by_default="true"> + <option name="m_regex" value="[A-Z][A-Za-z\d]*TestCase" /> + <option name="m_minLength" value="12" /> + <option name="m_maxLength" value="64" /> + </inspection_tool> + <inspection_tool class="JUnitTestClassNamingConvention" enabled="true" level="WARNING" enabled_by_default="true"> + <option name="m_regex" value="[A-Z][A-Za-z\d]*Test" /> + <option name="m_minLength" value="8" /> + <option name="m_maxLength" value="64" /> + </inspection_tool> + <inspection_tool class="JavaDoc" enabled="true" level="INFO" enabled_by_default="true"> + <option name="TOP_LEVEL_CLASS_OPTIONS"> + <value> + <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" /> + <option name="REQUIRED_TAGS" value="" /> + </value> + </option> + <option name="INNER_CLASS_OPTIONS"> + <value> + <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" /> + <option name="REQUIRED_TAGS" value="" /> + </value> + </option> + <option name="METHOD_OPTIONS"> + <value> + <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" /> + <option name="REQUIRED_TAGS" value="@return@param@throws or @exception" /> + </value> + </option> + <option name="FIELD_OPTIONS"> + <value> + <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" /> + <option name="REQUIRED_TAGS" value="" /> + </value> + </option> + <option name="IGNORE_DEPRECATED" value="false" /> + <option name="IGNORE_JAVADOC_PERIOD" value="true" /> + <option name="IGNORE_DUPLICATED_THROWS" value="false" /> + <option name="IGNORE_POINT_TO_ITSELF" value="false" /> + <option name="myAdditionalJavadocTags" value="" /> + </inspection_tool> + <inspection_tool class="JavadocReference" enabled="true" level="INFO" enabled_by_default="true" /> + <inspection_tool class="JpaDataSourceORMInspection" enabled="false" level="ERROR" enabled_by_default="false" /> + <inspection_tool class="MisorderedAssertEqualsParameters" enabled="true" level="WARNING" enabled_by_default="true" /> + <inspection_tool class="MissingDeprecatedAnnotation" enabled="true" level="WARNING" enabled_by_default="true" /> + <inspection_tool class="MissingOverrideAnnotation" enabled="true" level="WARNING" enabled_by_default="true"> + <option name="ignoreObjectMethods" value="true" /> + <option name="ignoreAnonymousClassMethods" value="false" /> + </inspection_tool> + <inspection_tool class="ProtectedField" enabled="true" level="WARNING" enabled_by_default="true" /> + <inspection_tool class="PublicConstructorInNonPublicClass" enabled="true" level="WARNING" enabled_by_default="true" /> + <inspection_tool class="PublicField" enabled="true" level="WARNING" enabled_by_default="true"> + <option name="ignoreEnums" value="false" /> + <option name="ignorableAnnotations"> + <value /> + </option> + </inspection_tool> + <inspection_tool class="RedundantImplements" enabled="true" level="WARNING" enabled_by_default="true"> + <option name="ignoreSerializable" value="false" /> + <option name="ignoreCloneable" value="false" /> + </inspection_tool> + <inspection_tool class="SimplifiableIfStatement" enabled="false" level="WARNING" enabled_by_default="false" /> + <inspection_tool class="StaticSuite" enabled="true" level="WARNING" enabled_by_default="true" /> + <inspection_tool class="SystemOutErr" enabled="true" level="WARNING" enabled_by_default="true" /> + <inspection_tool class="TextLabelInSwitchStatement" enabled="true" level="WARNING" enabled_by_default="true" /> + <inspection_tool class="TodoComment" enabled="true" level="WARNING" enabled_by_default="true" /> + <inspection_tool class="TooBroadScope" enabled="true" level="WARNING" enabled_by_default="true"> + <option name="m_allowConstructorAsInitializer" value="false" /> + <option name="m_onlyLookAtBlocks" value="false" /> + </inspection_tool> + <inspection_tool class="UnnecessaryInterfaceModifier" enabled="true" level="WARNING" enabled_by_default="true" /> + <inspection_tool class="UtilityClassWithPublicConstructor" enabled="true" level="WARNING" enabled_by_default="true" /> + </profile> + </profiles> + <option name="PROJECT_PROFILE" value="Project Default" /> + <option name="USE_PROJECT_PROFILE" value="true" /> + <version value="1.0" /> + </component> + <component name="IssueNavigationConfiguration"> + <option name="links"> + <list> + <IssueNavigationLink> + <option name="issueRegexp" value="[A-Z]+\-\d+" /> + <option name="linkRegexp" value="http://jira.springframework.org/browse/$0" /> + </IssueNavigationLink> + </list> + </option> + </component> + <component name="JavadocGenerationManager"> + <option name="OUTPUT_DIRECTORY" /> + <option name="OPTION_SCOPE" value="protected" /> + <option name="OPTION_HIERARCHY" value="true" /> + <option name="OPTION_NAVIGATOR" value="true" /> + <option name="OPTION_INDEX" value="true" /> + <option name="OPTION_SEPARATE_INDEX" value="true" /> + <option name="OPTION_DOCUMENT_TAG_USE" value="false" /> + <option name="OPTION_DOCUMENT_TAG_AUTHOR" value="false" /> + <option name="OPTION_DOCUMENT_TAG_VERSION" value="false" /> + <option name="OPTION_DOCUMENT_TAG_DEPRECATED" value="true" /> + <option name="OPTION_DEPRECATED_LIST" value="true" /> + <option name="OTHER_OPTIONS" value="" /> + <option name="HEAP_SIZE" /> + <option name="LOCALE" /> + <option name="OPEN_IN_BROWSER" value="true" /> + </component> + <component name="LogConsolePreferences"> + <option name="FILTER_ERRORS" value="false" /> + <option name="FILTER_WARNINGS" value="false" /> + <option name="FILTER_INFO" value="true" /> + <option name="CUSTOM_FILTER" /> + </component> + <component name="MavenBuilder"> + <option name="jreName" value="1.4" /> + <option name="runMavenInBackground" value="true" /> + </component> + <component name="Palette2"> + <group name="Swing"> + <item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false"> + <default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" /> + </item> + <item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false"> + <default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" /> + </item> + <item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false"> + <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" /> + </item> + <item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true"> + <default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" /> + </item> + <item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false"> + <default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" /> + <initial-values> + <property name="text" value="Button" /> + </initial-values> + </item> + <item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false"> + <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" /> + <initial-values> + <property name="text" value="RadioButton" /> + </initial-values> + </item> + <item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false"> + <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" /> + <initial-values> + <property name="text" value="CheckBox" /> + </initial-values> + </item> + <item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false"> + <default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" /> + <initial-values> + <property name="text" value="Label" /> + </initial-values> + </item> + <item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true"> + <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1"> + <preferred-size width="150" height="-1" /> + </default-constraints> + </item> + <item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true"> + <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1"> + <preferred-size width="150" height="-1" /> + </default-constraints> + </item> + <item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true"> + <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1"> + <preferred-size width="150" height="-1" /> + </default-constraints> + </item> + <item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true"> + <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> + <preferred-size width="150" height="50" /> + </default-constraints> + </item> + <item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true"> + <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> + <preferred-size width="150" height="50" /> + </default-constraints> + </item> + <item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true"> + <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> + <preferred-size width="150" height="50" /> + </default-constraints> + </item> + <item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true"> + <default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" /> + </item> + <item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false"> + <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> + <preferred-size width="150" height="50" /> + </default-constraints> + </item> + <item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false"> + <default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3"> + <preferred-size width="150" height="50" /> + </default-constraints> + </item> + <item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false"> + <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> + <preferred-size width="150" height="50" /> + </default-constraints> + </item> + <item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false"> + <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3"> + <preferred-size width="200" height="200" /> + </default-constraints> + </item> + <item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false"> + <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3"> + <preferred-size width="200" height="200" /> + </default-constraints> + </item> + <item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true"> + <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" /> + </item> + <item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false"> + <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" /> + </item> + <item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false"> + <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" /> + </item> + <item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false"> + <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" /> + </item> + <item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false"> + <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1"> + <preferred-size width="-1" height="20" /> + </default-constraints> + </item> + <item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false"> + <default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" /> + </item> + <item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false"> + <default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" /> + </item> + </group> + </component> + <component name="ProjectCodeStyleSettingsManager"> + <option name="PER_PROJECT_SETTINGS"> + <value> + <option name="JAVA_INDENT_OPTIONS"> + <value> + <option name="INDENT_SIZE" value="4" /> + <option name="CONTINUATION_INDENT_SIZE" value="8" /> + <option name="TAB_SIZE" value="4" /> + <option name="USE_TAB_CHARACTER" value="true" /> + <option name="SMART_TABS" value="false" /> + <option name="LABEL_INDENT_SIZE" value="0" /> + <option name="LABEL_INDENT_ABSOLUTE" value="false" /> + <option name="USE_RELATIVE_INDENTS" value="false" /> + </value> + </option> + <option name="LINE_SEPARATOR" value=" " /> + <option name="PREFER_LONGER_NAMES" value="false" /> + <option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999" /> + <option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="1" /> + <option name="IMPORT_LAYOUT_TABLE"> + <value> + <package name="java" withSubpackages="true" static="false" /> + <package name="javax" withSubpackages="true" static="false" /> + <emptyLine /> + <package name="" withSubpackages="true" static="false" /> + <emptyLine /> + <package name="org.springframework" withSubpackages="true" static="false" /> + <emptyLine /> + <package name="" withSubpackages="true" static="true" /> + </value> + </option> + <option name="JD_ALIGN_PARAM_COMMENTS" value="false" /> + <option name="JD_ALIGN_EXCEPTION_COMMENTS" value="false" /> + <option name="JD_P_AT_EMPTY_LINES" value="false" /> + <option name="JD_DO_NOT_WRAP_ONE_LINE_COMMENTS" value="true" /> + <option name="JD_KEEP_EMPTY_PARAMETER" value="false" /> + <option name="JD_KEEP_EMPTY_EXCEPTION" value="false" /> + <option name="JD_KEEP_EMPTY_RETURN" value="false" /> + <option name="KEEP_LINE_BREAKS" value="false" /> + <option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1" /> + <option name="KEEP_BLANK_LINES_IN_CODE" value="1" /> + <option name="BLANK_LINES_AROUND_FIELD" value="1" /> + <option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1" /> + <option name="ELSE_ON_NEW_LINE" value="true" /> + <option name="WHILE_ON_NEW_LINE" value="true" /> + <option name="CATCH_ON_NEW_LINE" value="true" /> + <option name="FINALLY_ON_NEW_LINE" value="true" /> + <option name="ALIGN_MULTILINE_PARAMETERS" value="false" /> + <option name="ALIGN_MULTILINE_FOR" value="false" /> + <option name="CALL_PARAMETERS_WRAP" value="1" /> + <option name="METHOD_PARAMETERS_WRAP" value="5" /> + <option name="EXTENDS_LIST_WRAP" value="1" /> + <option name="THROWS_LIST_WRAP" value="1" /> + <option name="EXTENDS_KEYWORD_WRAP" value="1" /> + <option name="THROWS_KEYWORD_WRAP" value="1" /> + <option name="METHOD_CALL_CHAIN_WRAP" value="1" /> + <option name="BINARY_OPERATION_WRAP" value="1" /> + <option name="TERNARY_OPERATION_WRAP" value="1" /> + <option name="FOR_STATEMENT_WRAP" value="5" /> + <option name="ARRAY_INITIALIZER_WRAP" value="1" /> + <option name="ASSIGNMENT_WRAP" value="1" /> + <option name="WRAP_COMMENTS" value="true" /> + <option name="IF_BRACE_FORCE" value="3" /> + <option name="DOWHILE_BRACE_FORCE" value="3" /> + <option name="WHILE_BRACE_FORCE" value="3" /> + <option name="FOR_BRACE_FORCE" value="3" /> + <XML> + <option name="XML_KEEP_WHITESPACES" value="true" /> + <option name="XML_TEXT_WRAP" value="0" /> + <option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" /> + </XML> + <ADDITIONAL_INDENT_OPTIONS fileType="gsp"> + <option name="INDENT_SIZE" value="2" /> + </ADDITIONAL_INDENT_OPTIONS> + <ADDITIONAL_INDENT_OPTIONS fileType="sass"> + <option name="INDENT_SIZE" value="2" /> + </ADDITIONAL_INDENT_OPTIONS> + <ADDITIONAL_INDENT_OPTIONS fileType="txt"> + <option name="INDENT_SIZE" value="2" /> + </ADDITIONAL_INDENT_OPTIONS> + <ADDITIONAL_INDENT_OPTIONS fileType="yml"> + <option name="INDENT_SIZE" value="2" /> + </ADDITIONAL_INDENT_OPTIONS> + <codeStyleSettings language="CFML"> + <option name="KEEP_LINE_BREAKS" value="false" /> + <option name="KEEP_BLANK_LINES_IN_CODE" value="1" /> + <option name="ELSE_ON_NEW_LINE" value="true" /> + <option name="WHILE_ON_NEW_LINE" value="true" /> + <option name="CATCH_ON_NEW_LINE" value="true" /> + <option name="ALIGN_MULTILINE_PARAMETERS" value="false" /> + <option name="ALIGN_MULTILINE_FOR" value="false" /> + <option name="CALL_PARAMETERS_WRAP" value="1" /> + <option name="METHOD_PARAMETERS_WRAP" value="5" /> + <option name="BINARY_OPERATION_WRAP" value="1" /> + <option name="TERNARY_OPERATION_WRAP" value="1" /> + <option name="FOR_STATEMENT_WRAP" value="5" /> + <option name="ASSIGNMENT_WRAP" value="1" /> + <option name="PARENT_SETTINGS_INSTALLED" value="true" /> + </codeStyleSettings> + <codeStyleSettings language="ECMA Script Level 4"> + <option name="KEEP_LINE_BREAKS" value="false" /> + <option name="KEEP_BLANK_LINES_IN_CODE" value="1" /> + <option name="ELSE_ON_NEW_LINE" value="true" /> + <option name="WHILE_ON_NEW_LINE" value="true" /> + <option name="CATCH_ON_NEW_LINE" value="true" /> + <option name="FINALLY_ON_NEW_LINE" value="true" /> + <option name="ALIGN_MULTILINE_PARAMETERS" value="false" /> + <option name="ALIGN_MULTILINE_FOR" value="false" /> + <option name="CALL_PARAMETERS_WRAP" value="1" /> + <option name="METHOD_PARAMETERS_WRAP" value="5" /> + <option name="EXTENDS_LIST_WRAP" value="1" /> + <option name="EXTENDS_KEYWORD_WRAP" value="1" /> + <option name="BINARY_OPERATION_WRAP" value="1" /> + <option name="TERNARY_OPERATION_WRAP" value="1" /> + <option name="FOR_STATEMENT_WRAP" value="5" /> + <option name="ARRAY_INITIALIZER_WRAP" value="1" /> + <option name="ASSIGNMENT_WRAP" value="1" /> + <option name="IF_BRACE_FORCE" value="3" /> + <option name="DOWHILE_BRACE_FORCE" value="3" /> + <option name="WHILE_BRACE_FORCE" value="3" /> + <option name="FOR_BRACE_FORCE" value="3" /> + <option name="PARENT_SETTINGS_INSTALLED" value="true" /> + </codeStyleSettings> + <codeStyleSettings language="Groovy"> + <option name="KEEP_LINE_BREAKS" value="false" /> + <option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1" /> + <option name="KEEP_BLANK_LINES_IN_CODE" value="1" /> + <option name="BLANK_LINES_AROUND_FIELD" value="1" /> + <option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1" /> + <option name="ELSE_ON_NEW_LINE" value="true" /> + <option name="WHILE_ON_NEW_LINE" value="true" /> + <option name="CATCH_ON_NEW_LINE" value="true" /> + <option name="FINALLY_ON_NEW_LINE" value="true" /> + <option name="ALIGN_MULTILINE_PARAMETERS" value="false" /> + <option name="ALIGN_MULTILINE_FOR" value="false" /> + <option name="CALL_PARAMETERS_WRAP" value="1" /> + <option name="METHOD_PARAMETERS_WRAP" value="5" /> + <option name="EXTENDS_LIST_WRAP" value="1" /> + <option name="THROWS_LIST_WRAP" value="1" /> + <option name="EXTENDS_KEYWORD_WRAP" value="1" /> + <option name="THROWS_KEYWORD_WRAP" value="1" /> + <option name="METHOD_CALL_CHAIN_WRAP" value="1" /> + <option name="BINARY_OPERATION_WRAP" value="1" /> + <option name="TERNARY_OPERATION_WRAP" value="1" /> + <option name="FOR_STATEMENT_WRAP" value="5" /> + <option name="ARRAY_INITIALIZER_WRAP" value="1" /> + <option name="ASSIGNMENT_WRAP" value="1" /> + <option name="WRAP_COMMENTS" value="true" /> + <option name="IF_BRACE_FORCE" value="3" /> + <option name="DOWHILE_BRACE_FORCE" value="3" /> + <option name="WHILE_BRACE_FORCE" value="3" /> + <option name="FOR_BRACE_FORCE" value="3" /> + <option name="PARENT_SETTINGS_INSTALLED" value="true" /> + <indentOptions> + <option name="INDENT_SIZE" value="2" /> + </indentOptions> + </codeStyleSettings> + <codeStyleSettings language="JAVA"> + <option name="KEEP_LINE_BREAKS" value="false" /> + <option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1" /> + <option name="KEEP_BLANK_LINES_IN_CODE" value="1" /> + <option name="BLANK_LINES_AROUND_FIELD" value="1" /> + <option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1" /> + <option name="ELSE_ON_NEW_LINE" value="true" /> + <option name="WHILE_ON_NEW_LINE" value="true" /> + <option name="CATCH_ON_NEW_LINE" value="true" /> + <option name="FINALLY_ON_NEW_LINE" value="true" /> + <option name="ALIGN_MULTILINE_PARAMETERS" value="false" /> + <option name="ALIGN_MULTILINE_FOR" value="false" /> + <option name="CALL_PARAMETERS_WRAP" value="1" /> + <option name="METHOD_PARAMETERS_WRAP" value="5" /> + <option name="EXTENDS_LIST_WRAP" value="1" /> + <option name="THROWS_LIST_WRAP" value="1" /> + <option name="EXTENDS_KEYWORD_WRAP" value="1" /> + <option name="THROWS_KEYWORD_WRAP" value="1" /> + <option name="METHOD_CALL_CHAIN_WRAP" value="1" /> + <option name="BINARY_OPERATION_WRAP" value="1" /> + <option name="TERNARY_OPERATION_WRAP" value="1" /> + <option name="FOR_STATEMENT_WRAP" value="5" /> + <option name="ARRAY_INITIALIZER_WRAP" value="1" /> + <option name="ASSIGNMENT_WRAP" value="1" /> + <option name="WRAP_COMMENTS" value="true" /> + <option name="IF_BRACE_FORCE" value="3" /> + <option name="DOWHILE_BRACE_FORCE" value="3" /> + <option name="WHILE_BRACE_FORCE" value="3" /> + <option name="FOR_BRACE_FORCE" value="3" /> + <option name="PARENT_SETTINGS_INSTALLED" value="true" /> + <indentOptions> + <option name="USE_TAB_CHARACTER" value="true" /> + </indentOptions> + </codeStyleSettings> + <codeStyleSettings language="JavaScript"> + <option name="KEEP_LINE_BREAKS" value="false" /> + <option name="KEEP_BLANK_LINES_IN_CODE" value="1" /> + <option name="ELSE_ON_NEW_LINE" value="true" /> + <option name="WHILE_ON_NEW_LINE" value="true" /> + <option name="CATCH_ON_NEW_LINE" value="true" /> + <option name="FINALLY_ON_NEW_LINE" value="true" /> + <option name="ALIGN_MULTILINE_PARAMETERS" value="false" /> + <option name="ALIGN_MULTILINE_FOR" value="false" /> + <option name="CALL_PARAMETERS_WRAP" value="1" /> + <option name="METHOD_PARAMETERS_WRAP" value="5" /> + <option name="BINARY_OPERATION_WRAP" value="1" /> + <option name="TERNARY_OPERATION_WRAP" value="1" /> + <option name="FOR_STATEMENT_WRAP" value="5" /> + <option name="ARRAY_INITIALIZER_WRAP" value="1" /> + <option name="ASSIGNMENT_WRAP" value="1" /> + <option name="IF_BRACE_FORCE" value="3" /> + <option name="DOWHILE_BRACE_FORCE" value="3" /> + <option name="WHILE_BRACE_FORCE" value="3" /> + <option name="FOR_BRACE_FORCE" value="3" /> + <option name="PARENT_SETTINGS_INSTALLED" value="true" /> + <indentOptions> + <option name="CONTINUATION_INDENT_SIZE" value="8" /> + </indentOptions> + </codeStyleSettings> + <codeStyleSettings language="XML"> + <indentOptions> + <option name="USE_TAB_CHARACTER" value="true" /> + </indentOptions> + </codeStyleSettings> + </value> + </option> + <option name="USE_PER_PROJECT_SETTINGS" value="true" /> + </component> + <component name="ProjectDetails"> + <option name="projectName" value="spring-framework" /> + </component> + <component name="ProjectKey"> + <option name="state" value="https://src.springframework.org/svn/spring-framework/trunk/spring-framework.ipr" /> + </component> + <component name="ProjectModuleManager"> + <modules> + <module fileurl="file://$PROJECT_DIR$/org.springframework.aop/aop.iml" filepath="$PROJECT_DIR$/org.springframework.aop/aop.iml" /> + <module fileurl="file://$PROJECT_DIR$/org.springframework.beans/beans.iml" filepath="$PROJECT_DIR$/org.springframework.beans/beans.iml" /> + <module fileurl="file://$PROJECT_DIR$/build-spring-framework/build.iml" filepath="$PROJECT_DIR$/build-spring-framework/build.iml" /> + <module fileurl="file://$PROJECT_DIR$/org.springframework.context/context.iml" filepath="$PROJECT_DIR$/org.springframework.context/context.iml" /> + <module fileurl="file://$PROJECT_DIR$/org.springframework.context.support/context-support.iml" filepath="$PROJECT_DIR$/org.springframework.context.support/context-support.iml" /> + <module fileurl="file://$PROJECT_DIR$/org.springframework.core/core.iml" filepath="$PROJECT_DIR$/org.springframework.core/core.iml" /> + <module fileurl="file://$PROJECT_DIR$/org.springframework.expression/expression.iml" filepath="$PROJECT_DIR$/org.springframework.expression/expression.iml" /> + <module fileurl="file://$PROJECT_DIR$/org.springframework.instrument/instrument.iml" filepath="$PROJECT_DIR$/org.springframework.instrument/instrument.iml" /> + <module fileurl="file://$PROJECT_DIR$/org.springframework.integration-tests/integration-tests.iml" filepath="$PROJECT_DIR$/org.springframework.integration-tests/integration-tests.iml" /> + <module fileurl="file://$PROJECT_DIR$/org.springframework.jdbc/jdbc.iml" filepath="$PROJECT_DIR$/org.springframework.jdbc/jdbc.iml" /> + <module fileurl="file://$PROJECT_DIR$/org.springframework.jms/jms.iml" filepath="$PROJECT_DIR$/org.springframework.jms/jms.iml" /> + <module fileurl="file://$PROJECT_DIR$/org.springframework.orm/orm.iml" filepath="$PROJECT_DIR$/org.springframework.orm/orm.iml" /> + <module fileurl="file://$PROJECT_DIR$/org.springframework.oxm/oxm.iml" filepath="$PROJECT_DIR$/org.springframework.oxm/oxm.iml" /> + <module fileurl="file://$PROJECT_DIR$/org.springframework.test/test.iml" filepath="$PROJECT_DIR$/org.springframework.test/test.iml" /> + <module fileurl="file://$PROJECT_DIR$/org.springframework.transaction/transaction.iml" filepath="$PROJECT_DIR$/org.springframework.transaction/transaction.iml" /> + <module fileurl="file://$PROJECT_DIR$/org.springframework.web/web.iml" filepath="$PROJECT_DIR$/org.springframework.web/web.iml" /> + <module fileurl="file://$PROJECT_DIR$/org.springframework.web.portlet/web-portlet.iml" filepath="$PROJECT_DIR$/org.springframework.web.portlet/web-portlet.iml" /> + <module fileurl="file://$PROJECT_DIR$/org.springframework.web.servlet/web-servlet.iml" filepath="$PROJECT_DIR$/org.springframework.web.servlet/web-servlet.iml" /> + </modules> + </component> + <component name="ProjectResources"> + <default-html-doctype>http://www.w3.org/1999/xhtml</default-html-doctype> + </component> + <component name="ProjectRootManager" version="2" languageLevel="JDK_1_5" assert-keyword="true" jdk-15="true" project-jdk-name="1.6" project-jdk-type="JavaSDK"> + <output url="file://$PROJECT_DIR$/target" /> + </component> + <component name="ResourceManagerContainer"> + <option name="myResourceBundles"> + <value> + <list size="0" /> + </value> + </option> + </component> + <component name="SvnBranchConfigurationManager"> + <option name="myConfigurationMap"> + <map> + <entry key="$PROJECT_DIR$"> + <value> + <SvnBranchConfiguration> + <option name="branchUrls"> + <list> + <option value="https://src.springframework.org/svn/spring-framework/branches" /> + <option value="https://src.springframework.org/svn/spring-framework/tags" /> + </list> + </option> + <option name="trunkUrl" value="https://src.springframework.org/svn/spring-framework/trunk" /> + </SvnBranchConfiguration> + </value> + </entry> + <entry key="$PROJECT_DIR$/org.springframework.web.servlet"> + <value> + <SvnBranchConfiguration> + <option name="branchUrls"> + <list> + <option value="https://src.springframework.org/svn/spring-framework/branches" /> + <option value="https://src.springframework.org/svn/spring-framework/tags" /> + </list> + </option> + <option name="trunkUrl" value="https://src.springframework.org/svn/spring-framework/trunk" /> + </SvnBranchConfiguration> + </value> + </entry> + <entry key="$PROJECT_DIR$/spring-build"> + <value> + <SvnBranchConfiguration> + <option name="branchUrls"> + <list> + <option value="https://src.springsource.org/svn/spring-build/branches" /> + <option value="https://src.springsource.org/svn/spring-build/tags" /> + </list> + </option> + <option name="trunkUrl" value="https://src.springsource.org/svn/spring-build/trunk" /> + </SvnBranchConfiguration> + </value> + </entry> + </map> + </option> + <option name="myVersion" value="124" /> + <option name="mySupportsUserInfoFilter" value="true" /> + </component> + <component name="SvnChangesBrowserSettings"> + <option name="USE_AUTHOR_FIELD" value="true" /> + <option name="AUTHOR" value="" /> + <option name="LOCATION" value="" /> + <option name="USE_PROJECT_SETTINGS" value="true" /> + <option name="USE_ALTERNATE_LOCATION" value="false" /> + </component> + <component name="ThePluginSettings"> + <option name="bambooConfiguration"> + <BambooProjectConfiguration> + <option name="tableConfiguration"> + <ProjectToolWindowTableConfiguration /> + </option> + </BambooProjectConfiguration> + </option> + <option name="crucibleConfiguration"> + <CrucibleProjectConfiguration> + <option name="crucibleFilters"> + <CrucibleFiltersBean /> + </option> + <option name="tableConfiguration"> + <ProjectToolWindowTableConfiguration /> + </option> + </CrucibleProjectConfiguration> + </option> + <option name="jiraConfiguration"> + <JiraProjectConfiguration> + <option name="tableConfiguration"> + <ProjectToolWindowTableConfiguration /> + </option> + </JiraProjectConfiguration> + </option> + </component> + <component name="VCS.FileViewConfiguration"> + <option name="SELECTED_STATUSES" value="DEFAULT" /> + <option name="SELECTED_COLUMNS" value="DEFAULT" /> + <option name="SHOW_FILTERS" value="true" /> + <option name="CUSTOMIZE_VIEW" value="true" /> + <option name="SHOW_FILE_HISTORY_AS_TREE" value="true" /> + </component> + <component name="VcsDirectoryMappings"> + <mapping directory="" vcs="Git" /> + </component> + <component name="WebServicesPlugin" addRequiredLibraries="true" /> + <component name="com.intellij.ide.util.scopeChooser.ScopeChooserConfigurable" proportions="" version="1"> + <option name="myLastEditedConfigurable" /> + </component> + <component name="com.intellij.jsf.UserDefinedFacesConfigs"> + <option name="USER_DEFINED_CONFIGS"> + <value> + <list size="0" /> + </value> + </option> + </component> + <component name="com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectRootMasterDetailsConfigurable" proportions="" version="1"> + <option name="myPlainMode" value="false" /> + <option name="myLastEditedConfigurable" /> + </component> + <component name="com.intellij.profile.ui.ErrorOptionsConfigurable" proportions="" version="1"> + <option name="myLastEditedConfigurable" /> + </component> + <component name="copyright"> + <Base> + <setting name="state" value="2" /> + </Base> + </component> + <component name="libraryTable"> + <library name="AOP Alliance"> + <CLASSES> + <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.aopalliance/com.springsource.org.aopalliance/1.0.0/com.springsource.org.aopalliance-1.0.0.jar!/" /> + </CLASSES> + <JAVADOC /> + <SOURCES> + <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.aopalliance/com.springsource.org.aopalliance/1.0.0/com.springsource.org.aopalliance-sources-1.0.0.jar!/" /> + </SOURCES> + </library> + <library name="ASM"> + <CLASSES> + <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.objectweb.asm/com.springsource.org.objectweb.asm/2.2.3/com.springsource.org.objectweb.asm-2.2.3.jar!/" /> + <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.objectweb.asm/com.springsource.org.objectweb.asm.commons/2.2.3/com.springsource.org.objectweb.asm.commons-2.2.3.jar!/" /> + </CLASSES> + <JAVADOC /> + <SOURCES> + <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.objectweb.asm/com.springsource.org.objectweb.asm/2.2.3/com.springsource.org.objectweb.asm-sources-2.2.3.jar!/" /> + <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.objectweb.asm/com.springsource.org.objectweb.asm.commons/2.2.3/com.springsource.org.objectweb.asm.commons-sources-2.2.3.jar!/" /> + </SOURCES> + </library> + <library name="AspectJ"> + <CLASSES> + <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.aspectj/com.springsource.org.aspectj.weaver/1.6.8.RELEASE/com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar!/" /> + </CLASSES> + <JAVADOC /> + <SOURCES> + <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.aspectj/com.springsource.org.aspectj.weaver/1.6.8.RELEASE/com.springsource.org.aspectj.weaver-sources-1.6.8.RELEASE.jar!/" /> + </SOURCES> + </library> + <library name="CGLIB"> + <CLASSES> + <root url="jar://$PROJECT_DIR$/ivy-cache/repository/net.sourceforge.cglib/com.springsource.net.sf.cglib/2.2.0/com.springsource.net.sf.cglib-2.2.0.jar!/" /> + </CLASSES> + <JAVADOC /> + <SOURCES> + <root url="jar://$PROJECT_DIR$/ivy-cache/repository/net.sourceforge.cglib/com.springsource.net.sf.cglib/2.2.0/com.springsource.net.sf.cglib-sources-2.2.0.jar!/" /> + </SOURCES> + </library> + <library name="Commons Collections"> + <CLASSES> + <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.apache.commons/com.springsource.org.apache.commons.collections/3.2.0/com.springsource.org.apache.commons.collections-3.2.0.jar!/" /> + </CLASSES> + <JAVADOC /> + <SOURCES> + <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.apache.commons/com.springsource.org.apache.commons.collections/3.2.0/com.springsource.org.apache.commons.collections-sources-3.2.0.jar!/" /> + </SOURCES> + </library> + <library name="Commons Logging"> + <CLASSES> + <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.apache.commons/com.springsource.org.apache.commons.logging/1.1.1/com.springsource.org.apache.commons.logging-1.1.1.jar!/" /> + </CLASSES> + <JAVADOC /> + <SOURCES> + <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.apache.commons/com.springsource.org.apache.commons.logging/1.1.1/com.springsource.org.apache.commons.logging-sources-1.1.1.jar!/" /> + </SOURCES> + </library> + <library name="Commons Pool"> + <CLASSES> + <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.apache.commons/com.springsource.org.apache.commons.pool/1.5.3/com.springsource.org.apache.commons.pool-1.5.3.jar!/" /> + </CLASSES> + <JAVADOC /> + <SOURCES> + <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.apache.commons/com.springsource.org.apache.commons.pool/1.5.3/com.springsource.org.apache.commons.pool-sources-1.5.3.jar!/" /> + </SOURCES> + </library> + <library name="EasyMock"> + <CLASSES> + <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.easymock/com.springsource.org.easymock/2.5.1/com.springsource.org.easymock-2.5.1.jar!/" /> + </CLASSES> + <JAVADOC /> + <SOURCES> + <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.easymock/com.springsource.org.easymock/2.5.1/com.springsource.org.easymock-sources-2.5.1.jar!/" /> + </SOURCES> + </library> + <library name="Hamcrest"> + <CLASSES> + <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.hamcrest/com.springsource.org.hamcrest/1.1.0/com.springsource.org.hamcrest-1.1.0.jar!/" /> + </CLASSES> + <JAVADOC /> + <SOURCES> + <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.hamcrest/com.springsource.org.hamcrest/1.1.0/com.springsource.org.hamcrest-sources-1.1.0.jar!/" /> + </SOURCES> + </library> + <library name="Jamon"> + <CLASSES> + <root url="jar://$PROJECT_DIR$/ivy-cache/repository/com.jamonapi/com.springsource.com.jamonapi/2.4.0/com.springsource.com.jamonapi-2.4.0.jar!/" /> + </CLASSES> + <JAVADOC /> + <SOURCES> + <root url="jar://$PROJECT_DIR$/ivy-cache/repository/com.jamonapi/com.springsource.com.jamonapi/2.4.0/com.springsource.com.jamonapi-sources-2.4.0.jar!/" /> + </SOURCES> + </library> + <library name="javax.el"> + <CLASSES> + <root url="jar://$PROJECT_DIR$/ivy-cache/repository/javax.el/com.springsource.javax.el/1.0.0/com.springsource.javax.el-1.0.0.jar!/" /> + </CLASSES> + <JAVADOC /> + <SOURCES> + <root url="jar://$PROJECT_DIR$/ivy-cache/repository/javax.el/com.springsource.javax.el/1.0.0/com.springsource.javax.el-sources-1.0.0.jar!/" /> + </SOURCES> + </library> + <library name="javax.inject"> + <CLASSES> + <root url="jar://$PROJECT_DIR$/ivy-cache/repository/javax.inject/com.springsource.javax.inject/1.0.0/com.springsource.javax.inject-1.0.0.jar!/" /> + </CLASSES> + <JAVADOC /> + <SOURCES> + <root url="jar://$PROJECT_DIR$/ivy-cache/repository/javax.inject/com.springsource.javax.inject/1.0.0/com.springsource.javax.inject-sources-1.0.0.jar!/" /> + </SOURCES> + </library> + <library name="javax.validation"> + <CLASSES> + <root url="jar://$PROJECT_DIR$/ivy-cache/repository/javax.validation/com.springsource.javax.validation/1.0.0.GA/com.springsource.javax.validation-1.0.0.GA.jar!/" /> + </CLASSES> + <JAVADOC /> + <SOURCES> + <root url="jar://$PROJECT_DIR$/ivy-cache/repository/javax.validation/com.springsource.javax.validation/1.0.0.GA/com.springsource.javax.validation-sources-1.0.0.GA.jar!/" /> + </SOURCES> + </library> + <library name="JUnit"> + <CLASSES> + <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.junit/com.springsource.org.junit/4.8.1/com.springsource.org.junit-4.8.1.jar!/" /> + </CLASSES> + <JAVADOC /> + <SOURCES> + <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.junit/com.springsource.org.junit/4.8.1/com.springsource.org.junit-sources-4.8.1.jar!/" /> + </SOURCES> + </library> + <library name="Log4j"> + <CLASSES> + <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.apache.log4j/com.springsource.org.apache.log4j/1.2.15/com.springsource.org.apache.log4j-1.2.15.jar!/" /> + </CLASSES> + <JAVADOC /> + <SOURCES> + <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.apache.log4j/com.springsource.org.apache.log4j/1.2.15/com.springsource.org.apache.log4j-sources-1.2.15.jar!/" /> + </SOURCES> + </library> + <library name="SLF4j"> + <CLASSES> + <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.slf4j/com.springsource.slf4j.api/1.5.3/com.springsource.slf4j.api-1.5.3.jar!/" /> + <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.slf4j/com.springsource.slf4j.jcl/1.5.3/com.springsource.slf4j.jcl-1.5.3.jar!/" /> + </CLASSES> + <JAVADOC /> + <SOURCES> + <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.slf4j/com.springsource.slf4j.api/1.5.3/com.springsource.slf4j.api-sources-1.5.3.jar!/" /> + <root url="jar://$PROJECT_DIR$/ivy-cache/repository/org.slf4j/com.springsource.slf4j.jcl/1.5.3/com.springsource.slf4j.jcl-sources-1.5.3.jar!/" /> + </SOURCES> + </library> + </component> +</project> + From e158f61e9367aabbcef60e0c2d0fca0c2e1083f2 Mon Sep 17 00:00:00 2001 From: Chris Beams <cbeams@vmware.com> Date: Fri, 16 Dec 2011 11:59:06 +0100 Subject: [PATCH 04/22] Increment version to 3.1.1.BUILD-SNAPSHOT --- build.properties | 10 +++++----- org.springframework.aop/pom.xml | 4 ++-- org.springframework.asm/pom.xml | 4 ++-- org.springframework.aspects/pom.xml | 4 ++-- org.springframework.beans/pom.xml | 4 ++-- org.springframework.context.support/pom.xml | 4 ++-- org.springframework.context/pom.xml | 4 ++-- org.springframework.core/pom.xml | 4 ++-- org.springframework.expression/pom.xml | 4 ++-- org.springframework.instrument.tomcat/pom.xml | 4 ++-- org.springframework.instrument/pom.xml | 4 ++-- org.springframework.integration-tests/pom.xml | 4 ++-- org.springframework.jdbc/pom.xml | 4 ++-- org.springframework.jms/pom.xml | 4 ++-- org.springframework.orm/pom.xml | 4 ++-- org.springframework.oxm/pom.xml | 4 ++-- org.springframework.spring-library/pom.xml | 2 +- org.springframework.spring-parent/pom.xml | 2 +- org.springframework.test/pom.xml | 4 ++-- org.springframework.transaction/pom.xml | 4 ++-- org.springframework.web.portlet/pom.xml | 4 ++-- org.springframework.web.servlet/pom.xml | 4 ++-- org.springframework.web.struts/pom.xml | 4 ++-- org.springframework.web/pom.xml | 4 ++-- 24 files changed, 49 insertions(+), 49 deletions(-) diff --git a/build.properties b/build.properties index 5f7d08a8dca..4f3d372542d 100644 --- a/build.properties +++ b/build.properties @@ -1,4 +1,4 @@ -version=3.1.0 +version=3.1.1 natural.name=spring-framework project.name=Spring Framework @@ -17,13 +17,13 @@ spring.osgi.range="${spring.osgi.range.nq}" aj.osgi.range="[1.6.8, 2.0.0)" ## For GA releases -release.type=release -build.stamp=RELEASE +#release.type=release +#build.stamp=RELEASE ## For milestone releases #release.type=milestone #build.stamp=M1 ## For trunk development / ci builds -#release.type=integration -#build.stamp=BUILD-SNAPSHOT +release.type=integration +build.stamp=BUILD-SNAPSHOT diff --git a/org.springframework.aop/pom.xml b/org.springframework.aop/pom.xml index d21357bb2ff..8a3a9085575 100644 --- a/org.springframework.aop/pom.xml +++ b/org.springframework.aop/pom.xml @@ -4,12 +4,12 @@ <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <packaging>jar</packaging> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> <parent> <groupId>org.springframework</groupId> <artifactId>spring-parent</artifactId> <relativePath>../org.springframework.spring-parent</relativePath> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> </parent> <dependencies> diff --git a/org.springframework.asm/pom.xml b/org.springframework.asm/pom.xml index 789e6ef3dae..3b089c93ba7 100644 --- a/org.springframework.asm/pom.xml +++ b/org.springframework.asm/pom.xml @@ -4,12 +4,12 @@ <groupId>org.springframework</groupId> <artifactId>spring-asm</artifactId> <packaging>jar</packaging> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> <parent> <groupId>org.springframework</groupId> <artifactId>spring-parent</artifactId> <relativePath>../org.springframework.spring-parent</relativePath> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> </parent> diff --git a/org.springframework.aspects/pom.xml b/org.springframework.aspects/pom.xml index 5feff8a29d0..423cbe54a07 100644 --- a/org.springframework.aspects/pom.xml +++ b/org.springframework.aspects/pom.xml @@ -4,12 +4,12 @@ <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <packaging>jar</packaging> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> <parent> <groupId>org.springframework</groupId> <artifactId>spring-parent</artifactId> <relativePath>../org.springframework.spring-parent</relativePath> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> </parent> <dependencies> diff --git a/org.springframework.beans/pom.xml b/org.springframework.beans/pom.xml index 664a729e864..56992da524e 100644 --- a/org.springframework.beans/pom.xml +++ b/org.springframework.beans/pom.xml @@ -4,12 +4,12 @@ <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <packaging>jar</packaging> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> <parent> <groupId>org.springframework</groupId> <artifactId>spring-parent</artifactId> <relativePath>../org.springframework.spring-parent</relativePath> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> </parent> <dependencies> diff --git a/org.springframework.context.support/pom.xml b/org.springframework.context.support/pom.xml index 5017fbf1732..f364d5c1c14 100644 --- a/org.springframework.context.support/pom.xml +++ b/org.springframework.context.support/pom.xml @@ -4,12 +4,12 @@ <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <packaging>jar</packaging> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> <parent> <groupId>org.springframework</groupId> <artifactId>spring-parent</artifactId> <relativePath>../org.springframework.spring-parent</relativePath> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> </parent> diff --git a/org.springframework.context/pom.xml b/org.springframework.context/pom.xml index 3d77ff69fc8..a51e768ea14 100644 --- a/org.springframework.context/pom.xml +++ b/org.springframework.context/pom.xml @@ -6,12 +6,12 @@ <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <packaging>jar</packaging> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> <parent> <groupId>org.springframework</groupId> <artifactId>spring-parent</artifactId> <relativePath>../org.springframework.spring-parent</relativePath> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> </parent> <dependencies> diff --git a/org.springframework.core/pom.xml b/org.springframework.core/pom.xml index 85f51005548..0fd00579f62 100644 --- a/org.springframework.core/pom.xml +++ b/org.springframework.core/pom.xml @@ -6,12 +6,12 @@ <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <packaging>jar</packaging> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> <parent> <groupId>org.springframework</groupId> <artifactId>spring-parent</artifactId> <relativePath>../org.springframework.spring-parent</relativePath> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> </parent> <dependencies> diff --git a/org.springframework.expression/pom.xml b/org.springframework.expression/pom.xml index 67a3902ae6b..b3795a6414e 100644 --- a/org.springframework.expression/pom.xml +++ b/org.springframework.expression/pom.xml @@ -4,12 +4,12 @@ <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <packaging>jar</packaging> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> <parent> <groupId>org.springframework</groupId> <artifactId>spring-parent</artifactId> <relativePath>../org.springframework.spring-parent</relativePath> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> </parent> <dependencies> diff --git a/org.springframework.instrument.tomcat/pom.xml b/org.springframework.instrument.tomcat/pom.xml index 113421d663a..93594d1b56e 100644 --- a/org.springframework.instrument.tomcat/pom.xml +++ b/org.springframework.instrument.tomcat/pom.xml @@ -4,12 +4,12 @@ <groupId>org.springframework</groupId> <artifactId>spring-instrument-tomcat</artifactId> <packaging>jar</packaging> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> <parent> <groupId>org.springframework</groupId> <artifactId>spring-parent</artifactId> <relativePath>../org.springframework.spring-parent</relativePath> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> </parent> <dependencies> diff --git a/org.springframework.instrument/pom.xml b/org.springframework.instrument/pom.xml index 0069efc1a56..d66b844c735 100644 --- a/org.springframework.instrument/pom.xml +++ b/org.springframework.instrument/pom.xml @@ -4,12 +4,12 @@ <groupId>org.springframework</groupId> <artifactId>spring-instrument</artifactId> <packaging>jar</packaging> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> <parent> <groupId>org.springframework</groupId> <artifactId>spring-parent</artifactId> <relativePath>../org.springframework.spring-parent</relativePath> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> </parent> </project> diff --git a/org.springframework.integration-tests/pom.xml b/org.springframework.integration-tests/pom.xml index 5eff89a392e..be0ee6b8aa9 100644 --- a/org.springframework.integration-tests/pom.xml +++ b/org.springframework.integration-tests/pom.xml @@ -4,12 +4,12 @@ <groupId>org.springframework</groupId> <artifactId>spring-integration-tests</artifactId> <packaging>jar</packaging> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> <parent> <groupId>org.springframework</groupId> <artifactId>spring-parent</artifactId> <relativePath>../org.springframework.spring-parent</relativePath> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> </parent> <dependencies> <dependency> diff --git a/org.springframework.jdbc/pom.xml b/org.springframework.jdbc/pom.xml index 9a7b1b3917d..dcf8f1c2c76 100644 --- a/org.springframework.jdbc/pom.xml +++ b/org.springframework.jdbc/pom.xml @@ -4,12 +4,12 @@ <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <packaging>jar</packaging> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> <parent> <groupId>org.springframework</groupId> <artifactId>spring-parent</artifactId> <relativePath>../org.springframework.spring-parent</relativePath> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> </parent> <dependencies> <dependency> diff --git a/org.springframework.jms/pom.xml b/org.springframework.jms/pom.xml index fccb1e4be6d..244442bb470 100644 --- a/org.springframework.jms/pom.xml +++ b/org.springframework.jms/pom.xml @@ -4,12 +4,12 @@ <groupId>org.springframework</groupId> <artifactId>spring-jms</artifactId> <packaging>jar</packaging> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> <parent> <groupId>org.springframework</groupId> <artifactId>spring-parent</artifactId> <relativePath>../org.springframework.spring-parent</relativePath> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> </parent> <dependencies> diff --git a/org.springframework.orm/pom.xml b/org.springframework.orm/pom.xml index b9afd4b7022..2916ab021c9 100644 --- a/org.springframework.orm/pom.xml +++ b/org.springframework.orm/pom.xml @@ -6,12 +6,12 @@ <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <packaging>jar</packaging> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> <parent> <groupId>org.springframework</groupId> <artifactId>spring-parent</artifactId> <relativePath>../org.springframework.spring-parent</relativePath> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> </parent> <dependencies> <dependency> diff --git a/org.springframework.oxm/pom.xml b/org.springframework.oxm/pom.xml index 2217326212d..a52d5f383b4 100644 --- a/org.springframework.oxm/pom.xml +++ b/org.springframework.oxm/pom.xml @@ -6,12 +6,12 @@ <groupId>org.springframework</groupId> <artifactId>spring-oxm</artifactId> <packaging>jar</packaging> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> <parent> <groupId>org.springframework</groupId> <artifactId>spring-parent</artifactId> <relativePath>../org.springframework.spring-parent</relativePath> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> </parent> <dependencies> diff --git a/org.springframework.spring-library/pom.xml b/org.springframework.spring-library/pom.xml index 67d84b46b7b..cae43e3ca2c 100644 --- a/org.springframework.spring-library/pom.xml +++ b/org.springframework.spring-library/pom.xml @@ -14,7 +14,7 @@ <groupId>org.springframework</groupId> <artifactId>spring-library</artifactId> <packaging>libd</packaging> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> <name>Spring Framework</name> <description>Spring is a layered Java/J2EE application platform, based on code published in Expert One-on-One J2EE Design and Development by Rod Johnson (Wrox, 2002). </description> diff --git a/org.springframework.spring-parent/pom.xml b/org.springframework.spring-parent/pom.xml index 2d8a567c2f7..1956c7d96c0 100644 --- a/org.springframework.spring-parent/pom.xml +++ b/org.springframework.spring-parent/pom.xml @@ -14,7 +14,7 @@ <artifactId>spring-parent</artifactId> <packaging>pom</packaging> <name>Spring Framework - Parent</name> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> <description>Spring Framework Parent</description> <scm> <url>https://fisheye.springframework.org/browse/spring-framework</url> diff --git a/org.springframework.test/pom.xml b/org.springframework.test/pom.xml index 628227cc639..85b279cf149 100644 --- a/org.springframework.test/pom.xml +++ b/org.springframework.test/pom.xml @@ -4,12 +4,12 @@ <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <packaging>jar</packaging> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> <parent> <groupId>org.springframework</groupId> <artifactId>spring-parent</artifactId> <relativePath>../org.springframework.spring-parent</relativePath> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> </parent> <dependencies> diff --git a/org.springframework.transaction/pom.xml b/org.springframework.transaction/pom.xml index a425a3d58ed..c043933a5c0 100644 --- a/org.springframework.transaction/pom.xml +++ b/org.springframework.transaction/pom.xml @@ -4,12 +4,12 @@ <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <packaging>jar</packaging> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> <parent> <groupId>org.springframework</groupId> <artifactId>spring-parent</artifactId> <relativePath>../org.springframework.spring-parent</relativePath> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> </parent> <dependencies> diff --git a/org.springframework.web.portlet/pom.xml b/org.springframework.web.portlet/pom.xml index 8375d335ceb..a29673296bf 100644 --- a/org.springframework.web.portlet/pom.xml +++ b/org.springframework.web.portlet/pom.xml @@ -4,12 +4,12 @@ <groupId>org.springframework</groupId> <artifactId>spring-webmvc-portlet</artifactId> <packaging>jar</packaging> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> <parent> <groupId>org.springframework</groupId> <artifactId>spring-parent</artifactId> <relativePath>../org.springframework.spring-parent</relativePath> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> </parent> <dependencies> diff --git a/org.springframework.web.servlet/pom.xml b/org.springframework.web.servlet/pom.xml index 5d73ea5fe0f..c528170f82f 100644 --- a/org.springframework.web.servlet/pom.xml +++ b/org.springframework.web.servlet/pom.xml @@ -6,12 +6,12 @@ <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <packaging>jar</packaging> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> <parent> <groupId>org.springframework</groupId> <artifactId>spring-parent</artifactId> <relativePath>../org.springframework.spring-parent</relativePath> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> </parent> <profiles> diff --git a/org.springframework.web.struts/pom.xml b/org.springframework.web.struts/pom.xml index ef83df0bf23..08c8d04d141 100644 --- a/org.springframework.web.struts/pom.xml +++ b/org.springframework.web.struts/pom.xml @@ -6,12 +6,12 @@ <groupId>org.springframework</groupId> <artifactId>spring-struts</artifactId> <packaging>jar</packaging> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> <parent> <groupId>org.springframework</groupId> <artifactId>spring-parent</artifactId> <relativePath>../org.springframework.spring-parent</relativePath> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> </parent> <dependencies> <dependency> diff --git a/org.springframework.web/pom.xml b/org.springframework.web/pom.xml index 40a18e0b6d6..834b5edb01d 100644 --- a/org.springframework.web/pom.xml +++ b/org.springframework.web/pom.xml @@ -5,12 +5,12 @@ <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <packaging>jar</packaging> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> <parent> <groupId>org.springframework</groupId> <artifactId>spring-parent</artifactId> <relativePath>../org.springframework.spring-parent</relativePath> - <version>3.1.0.RELEASE</version> + <version>3.1.1.BUILD-SNAPSHOT</version> </parent> <dependencies> From e1b645368a20592a0272c5f6843f6607e0ed0b93 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev <rstoyanchev@vmware.com> Date: Tue, 20 Dec 2011 10:57:27 -0500 Subject: [PATCH 05/22] Add missing (empty) source folders --- org.springframework.asm/src/main/resources/.gitignore | 0 org.springframework.asm/src/test/resources/.gitignore | 0 org.springframework.instrument.tomcat/src/test/java/.gitignore | 0 org.springframework.instrument/src/test/java/.gitignore | 0 org.springframework.web.struts/src/main/resources/.gitignore | 0 5 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 org.springframework.asm/src/main/resources/.gitignore create mode 100644 org.springframework.asm/src/test/resources/.gitignore create mode 100644 org.springframework.instrument.tomcat/src/test/java/.gitignore create mode 100644 org.springframework.instrument/src/test/java/.gitignore create mode 100644 org.springframework.web.struts/src/main/resources/.gitignore diff --git a/org.springframework.asm/src/main/resources/.gitignore b/org.springframework.asm/src/main/resources/.gitignore new file mode 100644 index 00000000000..e69de29bb2d diff --git a/org.springframework.asm/src/test/resources/.gitignore b/org.springframework.asm/src/test/resources/.gitignore new file mode 100644 index 00000000000..e69de29bb2d diff --git a/org.springframework.instrument.tomcat/src/test/java/.gitignore b/org.springframework.instrument.tomcat/src/test/java/.gitignore new file mode 100644 index 00000000000..e69de29bb2d diff --git a/org.springframework.instrument/src/test/java/.gitignore b/org.springframework.instrument/src/test/java/.gitignore new file mode 100644 index 00000000000..e69de29bb2d diff --git a/org.springframework.web.struts/src/main/resources/.gitignore b/org.springframework.web.struts/src/main/resources/.gitignore new file mode 100644 index 00000000000..e69de29bb2d From 88913f2b231c7bad0a535dcc11aab4dbf5ad9127 Mon Sep 17 00:00:00 2001 From: Chris Beams <cbeams@vmware.com> Date: Wed, 21 Dec 2011 14:42:42 +0100 Subject: [PATCH 06/22] Convert CRLF (dos) to LF (unix) Prior to this change, roughly 5% (~300 out of 6000+) of files under the source tree had CRLF line endings as opposed to the majority which have LF endings. This change normalizes these files to LF for consistency going forward. Command used: $ git ls-files | xargs file | grep CRLF | cut -d":" -f1 | xargs dos2unix Issue: SPR-5608 --- build.versions | 8 +- .../AsyncExecutionInterceptor.java | 206 +- .../TrickyAspectJPointcutExpressionTests.java | 348 +-- .../aop/support/ClassUtilsTests.java | 82 +- ...nterfaceDrivenDependencyInjectionAspect.aj | 108 +- .../cache/aspectj/AbstractCacheAspect.aj | 146 +- .../cache/aspectj/AnnotationCacheAspect.aj | 230 +- .../AbstractMethodMockingControl.aj | 394 ++-- ...otationDrivenStaticEntityMockingControl.aj | 136 +- .../staticmock/MockStaticEntityMethods.java | 68 +- .../aspectj/AbstractAsyncExecutionAspect.aj | 150 +- .../aspectj/AnnotationAsyncExecutionAspect.aj | 108 +- .../aspectj/AbstractTransactionAspect.aj | 186 +- .../aspectj/AnnotationTransactionAspect.aj | 150 +- .../AutoProxyWithCodeStyleAspectsTests.java | 64 +- .../aop/aspectj/autoproxy/CodeStyleAspect.aj | 72 +- ...SpringConfiguredWithAutoProxyingTests.java | 64 +- .../cache/aspectj/AbstractAnnotationTest.java | 1190 +++++------ .../cache/aspectj/AspectJAnnotationTest.java | 66 +- .../AnnotatedClassCacheableService.java | 274 +-- .../cache/config/CacheableService.java | 138 +- .../cache/config/DefaultCacheableService.java | 286 +-- ...nDrivenStaticEntityMockingControlTest.java | 292 +-- .../mock/staticmock/Delegate.java | 184 +- .../mock/staticmock/Person.java | 48 +- .../mock/staticmock/Person_Roo_Entity.aj | 200 +- .../AnnotationAsyncExecutionAspectTests.java | 356 ++-- .../ClassWithPrivateAnnotatedMember.java | 68 +- .../ClassWithProtectedAnnotatedMember.java | 68 +- .../transaction/aspectj/ITransactional.java | 20 +- ...ethodAnnotationOnClassWithNoInterface.java | 38 +- .../aspectj/TransactionAspectTests.java | 522 ++--- ...lAnnotationOnlyOnClassWithNoInterface.java | 40 +- org.springframework.aspects/template.mf | 40 +- .../beans/factory/annotation/Value.java | 122 +- .../factory/config/BeanExpressionContext.java | 168 +- .../config/BeanExpressionResolver.java | 90 +- .../config/ProviderCreatingFactoryBean.java | 190 +- .../beans/factory/support/ManagedArray.java | 90 +- .../support/SecurityContextProvider.java | 70 +- .../SimpleSecurityContextProvider.java | 116 +- .../SimpleConstructorNamespaceHandler.java | 300 +-- .../beans/propertyeditors/CurrencyEditor.java | 86 +- .../beans/propertyeditors/TimeZoneEditor.java | 92 +- .../beans/propertyeditors/UUIDEditor.java | 100 +- .../src/test/java/com/foo/Component.java | 52 +- .../foo/ComponentBeanDefinitionParser.java | 104 +- .../ComponentBeanDefinitionParserTest.java | 146 +- .../java/com/foo/ComponentFactoryBean.java | 70 +- .../com/foo/ComponentNamespaceHandler.java | 20 +- .../security/CallbacksSecurityTests.java | 1048 ++++----- .../beans/factory/support/security/policy.all | 4 +- .../security/support/ConstructorBean.java | 60 +- .../security/support/CustomCallbackBean.java | 60 +- .../security/support/CustomFactoryBean.java | 78 +- .../support/security/support/DestroyBean.java | 56 +- .../support/security/support/FactoryBean.java | 72 +- .../support/security/support/InitBean.java | 56 +- .../security/support/PropertyBean.java | 60 +- .../src/test/java/test/beans/DummyBean.java | 136 +- .../.settings/org.eclipse.jdt.ui.prefs | 8 +- .../commonj/TimerManagerAccessor.java | 326 +-- .../commonj/TimerManagerTaskScheduler.java | 348 +-- .../context/EmbeddedValueResolverAware.java | 82 +- .../AnnotatedBeanDefinitionReader.java | 354 +-- .../context/annotation/DependsOn.java | 108 +- .../Jsr330ScopeMetadataResolver.java | 222 +- .../annotation/ScopedProxyCreator.java | 86 +- .../GenericApplicationListenerAdapter.java | 146 +- .../event/SmartApplicationListener.java | 84 +- .../BeanExpressionContextAccessor.java | 110 +- .../expression/BeanFactoryAccessor.java | 110 +- .../expression/BeanFactoryResolver.java | 102 +- .../context/expression/MapAccessor.java | 168 +- .../StandardBeanExpressionResolver.java | 306 +-- .../support/GenericXmlApplicationContext.java | 268 +-- .../number/AbstractNumberFormatter.java | 148 +- .../GlassFishClassLoaderAdapter.java | 256 +-- .../jboss/JBossClassLoaderAdapter.java | 66 +- .../jboss/JBossLoadTimeWeaver.java | 182 +- .../classloading/jboss/JBossMCAdapter.java | 288 +-- .../jboss/JBossMCTranslatorAdapter.java | 162 +- .../jboss/JBossModulesAdapter.java | 140 +- .../classloading/jboss/package-info.java | 16 +- .../oc4j/OC4JClassLoaderAdapter.java | 174 +- .../oc4j/OC4JClassPreprocessorAdapter.java | 188 +- .../WebSphereClassLoaderAdapter.java | 222 +- .../WebSphereClassPreDefinePlugin.java | 200 +- .../websphere/WebSphereLoadTimeWeaver.java | 140 +- .../classloading/websphere/package-info.java | 16 +- .../jndi/JndiLocatorDelegate.java | 138 +- .../scheduling/TaskScheduler.java | 278 +-- .../springframework/scheduling/Trigger.java | 82 +- .../scheduling/TriggerContext.java | 96 +- .../scheduling/annotation/Async.java | 98 +- .../scheduling/annotation/AsyncResult.java | 126 +- .../scheduling/annotation/Scheduled.java | 142 +- .../concurrent/ConcurrentTaskScheduler.java | 374 ++-- .../ExecutorConfigurationSupport.java | 320 +-- .../concurrent/ReschedulingRunnable.java | 248 +-- .../concurrent/ThreadPoolTaskScheduler.java | 502 ++--- .../config/ScheduledTaskRegistrar.java | 426 ++-- .../scheduling/config/package-info.java | 18 +- .../scheduling/support/CronTrigger.java | 184 +- .../support/ScheduledMethodRunnable.java | 148 +- .../support/SimpleTriggerContext.java | 126 +- .../validation/annotation/package-info.java | 16 +- .../BeanValidationPostProcessor.java | 234 +- .../beanvalidation/CustomValidatorBean.java | 172 +- .../LocalValidatorFactoryBean.java | 514 ++--- .../LocaleContextMessageInterpolator.java | 112 +- .../MessageSourceResourceBundleLocator.java | 110 +- .../SpringConstraintValidatorFactory.java | 106 +- .../SpringValidatorAdapter.java | 432 ++-- .../beanvalidation/package-info.java | 22 +- .../cache/NoOpCacheManagerTests.java | 122 +- .../concurrent/ConcurrentCacheTests.java | 78 +- .../ConcurrentMapCacheManagerTests.java | 126 +- .../cache/config/AbstractAnnotationTests.java | 1240 +++++------ .../AnnotatedClassCacheableService.java | 274 +-- .../AnnotationNamespaceDrivenTests.java | 88 +- .../cache/config/AnnotationTests.java | 64 +- .../config/CacheAdviceNamespaceTests.java | 84 +- .../cache/config/CacheableService.java | 138 +- .../cache/config/DefaultCacheableService.java | 286 +-- .../cache/config/SomeKeyGenerator.java | 46 +- .../cache/ehcache/EhCacheCacheTests.java | 122 +- .../vendor/AbstractNativeCacheTests.java | 174 +- .../context/annotation/BeanAge.java | 32 +- ...PathFactoryBeanDefinitionScannerTests.java | 190 +- .../FooServiceDependentConverter.java | 76 +- .../annotation/jsr330/SpringAtInjectTck.java | 126 +- .../context/annotation4/DependencyBean.java | 54 +- .../annotation4/FactoryMethodComponent.java | 154 +- .../context/annotation4/SimpleBean.java | 72 +- .../context/annotation5/MyRepository.java | 74 +- .../ApplicationContextExpressionTests.java | 864 ++++---- .../GenericApplicationContextTests.java | 72 +- .../context/support/ResourceConverter.java | 64 +- .../context/support/Spr7283Tests.java | 96 +- .../annotation/AnnotationTestBeanFactory.java | 90 +- .../FactoryCreatedAnnotationTestBean.java | 50 +- .../annotation/AsyncExecutionTests.java | 522 ++--- .../groovy/GroovyAspectIntegrationTests.java | 200 +- .../scripting/groovy/GroovyAspectTests.java | 202 +- .../scripting/groovy/GroovyServiceImpl.grv | 20 +- .../springframework/scripting/groovy/Log.java | 30 +- .../scripting/groovy/LogUserAdvice.java | 82 +- .../scripting/groovy/TestService.java | 10 +- .../scripting/groovy/TestServiceImpl.java | 16 +- .../BeanValidationPostProcessorTests.java | 312 +-- .../beanvalidation/ValidatorFactoryTests.java | 540 ++--- .../core/ExceptionDepthComparator.java | 192 +- .../ConvertingPropertyEditorAdapter.java | 144 +- .../io/AbstractFileResolvingResource.java | 402 ++-- .../core/io/ClassRelativeResourceLoader.java | 150 +- .../org/springframework/core/io/VfsUtils.java | 504 ++--- .../core/io/WritableResource.java | 104 +- .../core/io/support/VfsPatternUtils.java | 106 +- .../core/serializer/support/package-info.java | 18 +- .../task/support/ExecutorServiceAdapter.java | 174 +- .../core/type/MethodMetadata.java | 158 +- .../core/type/StandardMethodMetadata.java | 216 +- .../AnnotationAttributesReadingVisitor.java | 300 +-- .../util/CompositeIterator.java | 148 +- .../util/LinkedCaseInsensitiveMap.java | 298 +-- .../core/ExceptionDepthComparatorTests.java | 210 +- .../core/GenericTypeResolverTests.java | 194 +- .../core/convert/TypeDescriptorTests.java | 1602 +++++++------- .../type/CachingMetadataReaderLeakTest.java | 158 +- .../util/CompositeIteratorTests.java | 196 +- .../expression/AccessException.java | 88 +- .../expression/BeanResolver.java | 74 +- .../expression/ConstructorExecutor.java | 90 +- .../expression/ConstructorResolver.java | 88 +- .../ExpressionInvocationTargetException.java | 98 +- .../expression/MethodExecutor.java | 88 +- .../expression/MethodFilter.java | 90 +- .../expression/MethodResolver.java | 88 +- .../springframework/expression/Operation.java | 58 +- .../expression/PropertyAccessor.java | 162 +- .../expression/TypeConverter.java | 106 +- .../expression/TypedValue.java | 160 +- .../common/TemplateParserContext.java | 130 +- .../expression/spel/ExpressionState.java | 484 ++--- .../spel/InternalParseException.java | 76 +- .../spel/SpelEvaluationException.java | 184 +- .../expression/spel/SpelMessage.java | 312 +-- .../expression/spel/SpelNode.java | 190 +- .../expression/spel/SpelParseException.java | 214 +- .../spel/SpelParserConfiguration.java | 94 +- .../expression/spel/ast/AstUtils.java | 144 +- .../expression/spel/ast/FormatHelper.java | 168 +- .../expression/spel/ast/InlineList.java | 240 +-- .../expression/spel/ast/IntLiteral.java | 80 +- .../expression/spel/ast/TypeCode.java | 122 +- .../spel/generated/SpringExpressions.g | 536 ++--- .../InternalSpelExpressionParser.java | 1700 +++++++-------- .../spel/standard/SpelExpressionParser.java | 126 +- .../expression/spel/standard/Token.java | 172 +- .../expression/spel/standard/TokenKind.java | 114 +- .../expression/spel/standard/Tokenizer.java | 1014 ++++----- .../spel/support/BooleanTypedValue.java | 92 +- .../spel/support/ReflectionHelper.java | 1014 ++++----- .../ReflectiveConstructorExecutor.java | 148 +- .../ReflectiveConstructorResolver.java | 240 +-- .../support/ReflectiveMethodExecutor.java | 154 +- .../support/ReflectiveMethodResolver.java | 394 ++-- .../support/ReflectivePropertyAccessor.java | 1054 ++++----- .../support/StandardOperatorOverloader.java | 76 +- .../spel/support/StandardTypeConverter.java | 152 +- .../expression/spel/SpelUtilities.java | 116 +- .../spel/ast/FormatHelperTests.java | 88 +- .../PropertiesConversionSpelTests.java | 212 +- .../spel/standard/SpelParserTests.java | 740 +++---- .../spel/support/StandardComponentsTests.java | 158 +- .../spel/testresources/TestAddress.java | 42 +- .../spel/testresources/TestPerson.java | 36 +- .../test/util/SerializationTestUtils.java | 200 +- .../config/DatabasePopulatorConfigUtils.java | 164 +- ...nitializeDatabaseBeanDefinitionParser.java | 110 +- .../embedded/OutputStreamFactory.java | 84 +- .../init/DatabasePopulatorUtils.java | 122 +- .../OracleJdbc4NativeJdbcExtractor.java | 120 +- .../jms/support/converter/MessageType.java | 64 +- .../hibernate3/LocalRegionFactoryProxy.java | 246 +-- .../hibernate4/LocalSessionFactoryBean.java | 670 +++--- .../SmartPersistenceUnitInfo.java | 80 +- .../HibernateJpaSessionFactoryBean.java | 112 +- .../CglibProxyBridgeMethodTests.java | 146 +- .../oxm/castor/CastorMappingException.java | 78 +- .../main/resources/META-INF/spring.schemas | 6 +- .../mock/web/portlet/MockCacheControl.java | 140 +- .../mock/web/portlet/MockEvent.java | 174 +- .../ServletWrappingPortletContext.java | 290 +-- .../expression/ExpressionUsageTests.java | 166 +- .../interceptor/TransactionAspectUtils.java | 270 +-- .../jta/ManagedTransactionAdapter.java | 178 +- .../TransactionManagerConfiguration.java | 90 +- .../web/portlet/NoHandlerFoundException.java | 106 +- .../bind/annotation/ActionMapping.java | 126 +- .../portlet/bind/annotation/EventMapping.java | 104 +- .../bind/annotation/RenderMapping.java | 124 +- .../bind/annotation/ResourceMapping.java | 98 +- .../portlet/context/PortletContextScope.java | 222 +- .../PortletModeParameterLookupKey.java | 128 +- .../web/portlet/mvc/EventAwareController.java | 86 +- .../portlet/mvc/ResourceAwareController.java | 96 +- .../mock/web/portlet/MockCacheControl.java | 140 +- .../mock/web/portlet/MockEvent.java | 174 +- .../ServletWrappingPortletContext.java | 290 +-- .../PortletApplicationContextScopeTests.java | 254 +-- .../servlet/mvc/condition/package-info.java | 16 +- .../mvc/method/annotation/package-info.java | 20 +- .../web/servlet/mvc/method/package-info.java | 18 +- .../SpringTilesApplicationContextFactory.java | 224 +- .../web/DelegatingServletInputStream.java | 132 +- .../web/DelegatingServletOutputStream.java | 148 +- .../mock/web/HeaderValueHolder.java | 192 +- .../mock/web/MockBodyContent.java | 394 ++-- .../mock/web/MockFilterChain.java | 140 +- .../mock/web/MockHttpServletRequest.java | 1896 ++++++++--------- .../mock/web/MockHttpSession.java | 492 ++--- .../mock/web/MockJspWriter.java | 382 ++-- .../mock/web/MockMultipartFile.java | 268 +-- .../web/MockMultipartHttpServletRequest.java | 262 +-- .../mock/web/MockPageContext.java | 740 +++---- .../mock/web/MockRequestDispatcher.java | 182 +- .../mock/web/MockServletConfig.java | 206 +- .../mock/web/MockServletContext.java | 984 ++++----- .../util/SerializationTestUtils.java | 130 +- .../view/tiles2/TilesConfigurerTests.java | 104 +- .../springframework/http/MediaTypeEditor.java | 100 +- .../xml/XmlAwareFormHttpMessageConverter.java | 70 +- ...sfiedServletRequestParameterException.java | 176 +- .../web/bind/annotation/Mapping.java | 70 +- .../web/bind/annotation/ValueConstants.java | 76 +- .../web/context/ContextCleanupListener.java | 154 +- .../DestructionCallbackBindingListener.java | 108 +- .../context/support/ServletContextScope.java | 222 +- .../web/method/annotation/package-info.java | 16 +- .../web/method/support/package-info.java | 16 +- .../StandardMultipartHttpServletRequest.java | 350 +-- .../StandardServletMultipartResolver.java | 146 +- .../web/DelegatingServletInputStream.java | 132 +- .../web/DelegatingServletOutputStream.java | 142 +- .../mock/web/HeaderValueHolder.java | 192 +- .../mock/web/MockHttpServletRequest.java | 1896 ++++++++--------- .../mock/web/MockHttpSession.java | 492 ++--- .../mock/web/MockRequestDispatcher.java | 182 +- .../mock/web/MockServletContext.java | 1014 ++++----- .../WebApplicationContextScopeTests.java | 200 +- .../SpringBeanAutowiringSupportTests.java | 124 +- 293 files changed, 31091 insertions(+), 31091 deletions(-) diff --git a/build.versions b/build.versions index a4e1c28bdb5..bdbac64d93c 100644 --- a/build.versions +++ b/build.versions @@ -1,4 +1,4 @@ -# common dependency versions -aspectj.version=1.6.8.RELEASE -junit.version=4.9.0 -testng.version=5.12.1 +# common dependency versions +aspectj.version=1.6.8.RELEASE +junit.version=4.9.0 +testng.version=5.12.1 diff --git a/org.springframework.aop/src/main/java/org/springframework/aop/interceptor/AsyncExecutionInterceptor.java b/org.springframework.aop/src/main/java/org/springframework/aop/interceptor/AsyncExecutionInterceptor.java index e64de27c6c0..6039ce304cd 100644 --- a/org.springframework.aop/src/main/java/org/springframework/aop/interceptor/AsyncExecutionInterceptor.java +++ b/org.springframework.aop/src/main/java/org/springframework/aop/interceptor/AsyncExecutionInterceptor.java @@ -1,103 +1,103 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.aop.interceptor; - -import java.util.concurrent.Callable; -import java.util.concurrent.Executor; -import java.util.concurrent.Future; - -import org.aopalliance.intercept.MethodInterceptor; -import org.aopalliance.intercept.MethodInvocation; - -import org.springframework.core.Ordered; -import org.springframework.core.task.AsyncTaskExecutor; -import org.springframework.core.task.support.TaskExecutorAdapter; -import org.springframework.util.Assert; -import org.springframework.util.ReflectionUtils; - -/** - * AOP Alliance <code>MethodInterceptor</code> that processes method invocations - * asynchronously, using a given {@link org.springframework.core.task.AsyncTaskExecutor}. - * Typically used with the {@link org.springframework.context.task.Async} annotation. - * - * <p>In terms of target method signatures, any parameter types are supported. - * However, the return type is constrained to either <code>void</code> or - * <code>java.util.concurrent.Future</code>. In the latter case, the Future handle - * returned from the proxy will be an actual asynchronous Future that can be used - * to track the result of the asynchronous method execution. However, since the - * target method needs to implement the same signature, it will have to return - * a temporary Future handle that just passes the return value through - * (like Spring's {@link org.springframework.scheduling.annotation.AsyncResult} - * or EJB 3.1's <code>javax.ejb.AsyncResult</code>). - * - * @author Juergen Hoeller - * @since 3.0 - * @see org.springframework.scheduling.annotation.Async - * @see org.springframework.scheduling.annotation.AsyncAnnotationAdvisor - */ -public class AsyncExecutionInterceptor implements MethodInterceptor, Ordered { - - private final AsyncTaskExecutor asyncExecutor; - - - /** - * Create a new AsyncExecutionInterceptor. - * @param asyncExecutor the Spring AsyncTaskExecutor to delegate to - */ - public AsyncExecutionInterceptor(AsyncTaskExecutor asyncExecutor) { - Assert.notNull(asyncExecutor, "TaskExecutor must not be null"); - this.asyncExecutor = asyncExecutor; - } - - /** - * Create a new AsyncExecutionInterceptor. - * @param asyncExecutor the <code>java.util.concurrent</code> Executor - * to delegate to (typically a {@link java.util.concurrent.ExecutorService} - */ - public AsyncExecutionInterceptor(Executor asyncExecutor) { - this.asyncExecutor = new TaskExecutorAdapter(asyncExecutor); - } - - - public Object invoke(final MethodInvocation invocation) throws Throwable { - Future result = this.asyncExecutor.submit(new Callable<Object>() { - public Object call() throws Exception { - try { - Object result = invocation.proceed(); - if (result instanceof Future) { - return ((Future) result).get(); - } - } - catch (Throwable ex) { - ReflectionUtils.rethrowException(ex); - } - return null; - } - }); - if (Future.class.isAssignableFrom(invocation.getMethod().getReturnType())) { - return result; - } - else { - return null; - } - } - - public int getOrder() { - return Ordered.HIGHEST_PRECEDENCE; - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.aop.interceptor; + +import java.util.concurrent.Callable; +import java.util.concurrent.Executor; +import java.util.concurrent.Future; + +import org.aopalliance.intercept.MethodInterceptor; +import org.aopalliance.intercept.MethodInvocation; + +import org.springframework.core.Ordered; +import org.springframework.core.task.AsyncTaskExecutor; +import org.springframework.core.task.support.TaskExecutorAdapter; +import org.springframework.util.Assert; +import org.springframework.util.ReflectionUtils; + +/** + * AOP Alliance <code>MethodInterceptor</code> that processes method invocations + * asynchronously, using a given {@link org.springframework.core.task.AsyncTaskExecutor}. + * Typically used with the {@link org.springframework.context.task.Async} annotation. + * + * <p>In terms of target method signatures, any parameter types are supported. + * However, the return type is constrained to either <code>void</code> or + * <code>java.util.concurrent.Future</code>. In the latter case, the Future handle + * returned from the proxy will be an actual asynchronous Future that can be used + * to track the result of the asynchronous method execution. However, since the + * target method needs to implement the same signature, it will have to return + * a temporary Future handle that just passes the return value through + * (like Spring's {@link org.springframework.scheduling.annotation.AsyncResult} + * or EJB 3.1's <code>javax.ejb.AsyncResult</code>). + * + * @author Juergen Hoeller + * @since 3.0 + * @see org.springframework.scheduling.annotation.Async + * @see org.springframework.scheduling.annotation.AsyncAnnotationAdvisor + */ +public class AsyncExecutionInterceptor implements MethodInterceptor, Ordered { + + private final AsyncTaskExecutor asyncExecutor; + + + /** + * Create a new AsyncExecutionInterceptor. + * @param asyncExecutor the Spring AsyncTaskExecutor to delegate to + */ + public AsyncExecutionInterceptor(AsyncTaskExecutor asyncExecutor) { + Assert.notNull(asyncExecutor, "TaskExecutor must not be null"); + this.asyncExecutor = asyncExecutor; + } + + /** + * Create a new AsyncExecutionInterceptor. + * @param asyncExecutor the <code>java.util.concurrent</code> Executor + * to delegate to (typically a {@link java.util.concurrent.ExecutorService} + */ + public AsyncExecutionInterceptor(Executor asyncExecutor) { + this.asyncExecutor = new TaskExecutorAdapter(asyncExecutor); + } + + + public Object invoke(final MethodInvocation invocation) throws Throwable { + Future result = this.asyncExecutor.submit(new Callable<Object>() { + public Object call() throws Exception { + try { + Object result = invocation.proceed(); + if (result instanceof Future) { + return ((Future) result).get(); + } + } + catch (Throwable ex) { + ReflectionUtils.rethrowException(ex); + } + return null; + } + }); + if (Future.class.isAssignableFrom(invocation.getMethod().getReturnType())) { + return result; + } + else { + return null; + } + } + + public int getOrder() { + return Ordered.HIGHEST_PRECEDENCE; + } + +} diff --git a/org.springframework.aop/src/test/java/org/springframework/aop/aspectj/TrickyAspectJPointcutExpressionTests.java b/org.springframework.aop/src/test/java/org/springframework/aop/aspectj/TrickyAspectJPointcutExpressionTests.java index be1fb06e37f..227c1553c31 100644 --- a/org.springframework.aop/src/test/java/org/springframework/aop/aspectj/TrickyAspectJPointcutExpressionTests.java +++ b/org.springframework.aop/src/test/java/org/springframework/aop/aspectj/TrickyAspectJPointcutExpressionTests.java @@ -1,174 +1,174 @@ -package org.springframework.aop.aspectj; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.lang.reflect.Method; - -import org.junit.Test; -import org.springframework.aop.Advisor; -import org.springframework.aop.MethodBeforeAdvice; -import org.springframework.aop.ThrowsAdvice; -import org.springframework.aop.framework.ProxyFactory; -import org.springframework.aop.support.DefaultPointcutAdvisor; -import org.springframework.core.OverridingClassLoader; - -/** - * @author Dave Syer - */ -public class TrickyAspectJPointcutExpressionTests { - - @Test - public void testManualProxyJavaWithUnconditionalPointcut() throws Exception { - TestService target = new TestServiceImpl(); - LogUserAdvice logAdvice = new LogUserAdvice(); - testAdvice(new DefaultPointcutAdvisor(logAdvice), logAdvice, target, "TestServiceImpl"); - } - - @Test - public void testManualProxyJavaWithStaticPointcut() throws Exception { - TestService target = new TestServiceImpl(); - LogUserAdvice logAdvice = new LogUserAdvice(); - AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); - pointcut.setExpression(String.format("execution(* %s.TestService.*(..))", getClass().getName())); - testAdvice(new DefaultPointcutAdvisor(pointcut, logAdvice), logAdvice, target, "TestServiceImpl"); - } - - @Test - public void testManualProxyJavaWithDynamicPointcut() throws Exception { - TestService target = new TestServiceImpl(); - LogUserAdvice logAdvice = new LogUserAdvice(); - AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); - pointcut.setExpression(String.format("@within(%s.Log)", getClass().getName())); - testAdvice(new DefaultPointcutAdvisor(pointcut, logAdvice), logAdvice, target, "TestServiceImpl"); - } - - @Test - public void testManualProxyJavaWithDynamicPointcutAndProxyTargetClass() throws Exception { - TestService target = new TestServiceImpl(); - LogUserAdvice logAdvice = new LogUserAdvice(); - AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); - pointcut.setExpression(String.format("@within(%s.Log)", getClass().getName())); - testAdvice(new DefaultPointcutAdvisor(pointcut, logAdvice), logAdvice, target, "TestServiceImpl", true); - } - - @Test - public void testManualProxyJavaWithStaticPointcutAndTwoClassLoaders() throws Exception { - - LogUserAdvice logAdvice = new LogUserAdvice(); - AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); - pointcut.setExpression(String.format("execution(* %s.TestService.*(..))", getClass().getName())); - - // Test with default class loader first... - testAdvice(new DefaultPointcutAdvisor(pointcut, logAdvice), logAdvice, new TestServiceImpl(), "TestServiceImpl"); - - // Then try again with a different class loader on the target... - SimpleThrowawayClassLoader loader = new SimpleThrowawayClassLoader(new TestServiceImpl().getClass().getClassLoader()); - // Make sure the interface is loaded from the parent class loader - loader.excludeClass(TestService.class.getName()); - loader.excludeClass(TestException.class.getName()); - TestService other = (TestService) loader.loadClass(TestServiceImpl.class.getName()).newInstance(); - testAdvice(new DefaultPointcutAdvisor(pointcut, logAdvice), logAdvice, other, "TestServiceImpl"); - - } - - private void testAdvice(Advisor advisor, LogUserAdvice logAdvice, TestService target, String message) - throws Exception { - testAdvice(advisor, logAdvice, target, message, false); - } - - private void testAdvice(Advisor advisor, LogUserAdvice logAdvice, TestService target, String message, - boolean proxyTargetClass) throws Exception { - - logAdvice.reset(); - - ProxyFactory factory = new ProxyFactory(target); - factory.setProxyTargetClass(proxyTargetClass); - factory.addAdvisor(advisor); - TestService bean = (TestService) factory.getProxy(); - - assertEquals(0, logAdvice.getCountThrows()); - try { - bean.sayHello(); - fail("Expected exception"); - } catch (TestException e) { - assertEquals(message, e.getMessage()); - } - assertEquals(1, logAdvice.getCountThrows()); - } - - public static class SimpleThrowawayClassLoader extends OverridingClassLoader { - - /** - * Create a new SimpleThrowawayClassLoader for the given class loader. - * @param parent the ClassLoader to build a throwaway ClassLoader for - */ - public SimpleThrowawayClassLoader(ClassLoader parent) { - super(parent); - } - - } - - public static class TestException extends RuntimeException { - - public TestException(String string) { - super(string); - } - - } - - @Target({ ElementType.METHOD, ElementType.TYPE }) - @Retention(RetentionPolicy.RUNTIME) - @Documented - @Inherited - public static @interface Log { - } - - public static interface TestService { - public String sayHello(); - } - - @Log - public static class TestServiceImpl implements TestService{ - public String sayHello() { - throw new TestException("TestServiceImpl"); - } - } - - public class LogUserAdvice implements MethodBeforeAdvice, ThrowsAdvice { - - private int countBefore = 0; - - private int countThrows = 0; - - public void before(Method method, Object[] objects, Object o) throws Throwable { - countBefore++; - } - - public void afterThrowing(Exception e) throws Throwable { - countThrows++; - throw e; - } - - public int getCountBefore() { - return countBefore; - } - - public int getCountThrows() { - return countThrows; - } - - public void reset() { - countThrows = 0; - countBefore = 0; - } - - } - -} +package org.springframework.aop.aspectj; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.reflect.Method; + +import org.junit.Test; +import org.springframework.aop.Advisor; +import org.springframework.aop.MethodBeforeAdvice; +import org.springframework.aop.ThrowsAdvice; +import org.springframework.aop.framework.ProxyFactory; +import org.springframework.aop.support.DefaultPointcutAdvisor; +import org.springframework.core.OverridingClassLoader; + +/** + * @author Dave Syer + */ +public class TrickyAspectJPointcutExpressionTests { + + @Test + public void testManualProxyJavaWithUnconditionalPointcut() throws Exception { + TestService target = new TestServiceImpl(); + LogUserAdvice logAdvice = new LogUserAdvice(); + testAdvice(new DefaultPointcutAdvisor(logAdvice), logAdvice, target, "TestServiceImpl"); + } + + @Test + public void testManualProxyJavaWithStaticPointcut() throws Exception { + TestService target = new TestServiceImpl(); + LogUserAdvice logAdvice = new LogUserAdvice(); + AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); + pointcut.setExpression(String.format("execution(* %s.TestService.*(..))", getClass().getName())); + testAdvice(new DefaultPointcutAdvisor(pointcut, logAdvice), logAdvice, target, "TestServiceImpl"); + } + + @Test + public void testManualProxyJavaWithDynamicPointcut() throws Exception { + TestService target = new TestServiceImpl(); + LogUserAdvice logAdvice = new LogUserAdvice(); + AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); + pointcut.setExpression(String.format("@within(%s.Log)", getClass().getName())); + testAdvice(new DefaultPointcutAdvisor(pointcut, logAdvice), logAdvice, target, "TestServiceImpl"); + } + + @Test + public void testManualProxyJavaWithDynamicPointcutAndProxyTargetClass() throws Exception { + TestService target = new TestServiceImpl(); + LogUserAdvice logAdvice = new LogUserAdvice(); + AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); + pointcut.setExpression(String.format("@within(%s.Log)", getClass().getName())); + testAdvice(new DefaultPointcutAdvisor(pointcut, logAdvice), logAdvice, target, "TestServiceImpl", true); + } + + @Test + public void testManualProxyJavaWithStaticPointcutAndTwoClassLoaders() throws Exception { + + LogUserAdvice logAdvice = new LogUserAdvice(); + AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); + pointcut.setExpression(String.format("execution(* %s.TestService.*(..))", getClass().getName())); + + // Test with default class loader first... + testAdvice(new DefaultPointcutAdvisor(pointcut, logAdvice), logAdvice, new TestServiceImpl(), "TestServiceImpl"); + + // Then try again with a different class loader on the target... + SimpleThrowawayClassLoader loader = new SimpleThrowawayClassLoader(new TestServiceImpl().getClass().getClassLoader()); + // Make sure the interface is loaded from the parent class loader + loader.excludeClass(TestService.class.getName()); + loader.excludeClass(TestException.class.getName()); + TestService other = (TestService) loader.loadClass(TestServiceImpl.class.getName()).newInstance(); + testAdvice(new DefaultPointcutAdvisor(pointcut, logAdvice), logAdvice, other, "TestServiceImpl"); + + } + + private void testAdvice(Advisor advisor, LogUserAdvice logAdvice, TestService target, String message) + throws Exception { + testAdvice(advisor, logAdvice, target, message, false); + } + + private void testAdvice(Advisor advisor, LogUserAdvice logAdvice, TestService target, String message, + boolean proxyTargetClass) throws Exception { + + logAdvice.reset(); + + ProxyFactory factory = new ProxyFactory(target); + factory.setProxyTargetClass(proxyTargetClass); + factory.addAdvisor(advisor); + TestService bean = (TestService) factory.getProxy(); + + assertEquals(0, logAdvice.getCountThrows()); + try { + bean.sayHello(); + fail("Expected exception"); + } catch (TestException e) { + assertEquals(message, e.getMessage()); + } + assertEquals(1, logAdvice.getCountThrows()); + } + + public static class SimpleThrowawayClassLoader extends OverridingClassLoader { + + /** + * Create a new SimpleThrowawayClassLoader for the given class loader. + * @param parent the ClassLoader to build a throwaway ClassLoader for + */ + public SimpleThrowawayClassLoader(ClassLoader parent) { + super(parent); + } + + } + + public static class TestException extends RuntimeException { + + public TestException(String string) { + super(string); + } + + } + + @Target({ ElementType.METHOD, ElementType.TYPE }) + @Retention(RetentionPolicy.RUNTIME) + @Documented + @Inherited + public static @interface Log { + } + + public static interface TestService { + public String sayHello(); + } + + @Log + public static class TestServiceImpl implements TestService{ + public String sayHello() { + throw new TestException("TestServiceImpl"); + } + } + + public class LogUserAdvice implements MethodBeforeAdvice, ThrowsAdvice { + + private int countBefore = 0; + + private int countThrows = 0; + + public void before(Method method, Object[] objects, Object o) throws Throwable { + countBefore++; + } + + public void afterThrowing(Exception e) throws Throwable { + countThrows++; + throw e; + } + + public int getCountBefore() { + return countBefore; + } + + public int getCountThrows() { + return countThrows; + } + + public void reset() { + countThrows = 0; + countBefore = 0; + } + + } + +} diff --git a/org.springframework.aop/src/test/java/org/springframework/aop/support/ClassUtilsTests.java b/org.springframework.aop/src/test/java/org/springframework/aop/support/ClassUtilsTests.java index fe016f6f2b0..1c250e966da 100644 --- a/org.springframework.aop/src/test/java/org/springframework/aop/support/ClassUtilsTests.java +++ b/org.springframework.aop/src/test/java/org/springframework/aop/support/ClassUtilsTests.java @@ -1,41 +1,41 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.aop.support; - -import junit.framework.TestCase; - -import org.springframework.aop.framework.ProxyFactory; -import test.beans.TestBean; -import org.springframework.util.ClassUtils; - -/** - * @author Colin Sampaleanu - * @author Juergen Hoeller - * @author Rob Harrop - * @author Rick Evans - */ -public class ClassUtilsTests extends TestCase { - - public void testGetShortNameForCglibClass() { - TestBean tb = new TestBean(); - ProxyFactory pf = new ProxyFactory(); - pf.setTarget(tb); - pf.setProxyTargetClass(true); - TestBean proxy = (TestBean) pf.getProxy(); - String className = ClassUtils.getShortName(proxy.getClass()); - assertEquals("Class name did not match", "TestBean", className); - } -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.aop.support; + +import junit.framework.TestCase; + +import org.springframework.aop.framework.ProxyFactory; +import test.beans.TestBean; +import org.springframework.util.ClassUtils; + +/** + * @author Colin Sampaleanu + * @author Juergen Hoeller + * @author Rob Harrop + * @author Rick Evans + */ +public class ClassUtilsTests extends TestCase { + + public void testGetShortNameForCglibClass() { + TestBean tb = new TestBean(); + ProxyFactory pf = new ProxyFactory(); + pf.setTarget(tb); + pf.setProxyTargetClass(true); + TestBean proxy = (TestBean) pf.getProxy(); + String className = ClassUtils.getShortName(proxy.getClass()); + assertEquals("Class name did not match", "TestBean", className); + } +} diff --git a/org.springframework.aspects/src/main/java/org/springframework/beans/factory/aspectj/GenericInterfaceDrivenDependencyInjectionAspect.aj b/org.springframework.aspects/src/main/java/org/springframework/beans/factory/aspectj/GenericInterfaceDrivenDependencyInjectionAspect.aj index 78f927ffad2..82795313e7c 100644 --- a/org.springframework.aspects/src/main/java/org/springframework/beans/factory/aspectj/GenericInterfaceDrivenDependencyInjectionAspect.aj +++ b/org.springframework.aspects/src/main/java/org/springframework/beans/factory/aspectj/GenericInterfaceDrivenDependencyInjectionAspect.aj @@ -1,54 +1,54 @@ -/* - * Copyright 2002-2008 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.beans.factory.aspectj; - -/** - * Generic-based dependency injection aspect. - * <p> - * This aspect allows users to implement efficient, type-safe dependency injection without - * the use of the @Configurable annotation. - * - * The subaspect of this aspect doesn't need to include any AOP constructs. - * For example, here is a subaspect that configures the <code>PricingStrategyClient</code> objects. - * <pre> - * aspect PricingStrategyDependencyInjectionAspect - * extends GenericInterfaceDrivenDependencyInjectionAspect<PricingStrategyClient> { - * private PricingStrategy pricingStrategy; - * - * public void configure(PricingStrategyClient bean) { - * bean.setPricingStrategy(pricingStrategy); - * } - * - * public void setPricingStrategy(PricingStrategy pricingStrategy) { - * this.pricingStrategy = pricingStrategy; - * } - * } - * </pre> - * @author Ramnivas Laddad - * @since 3.0.0 - */ -public abstract aspect GenericInterfaceDrivenDependencyInjectionAspect<I> extends AbstractInterfaceDrivenDependencyInjectionAspect { - declare parents: I implements ConfigurableObject; - - public pointcut inConfigurableBean() : within(I+); - - public final void configureBean(Object bean) { - configure((I)bean); - } - - // Unfortunately, erasure used with generics won't allow to use the same named method - protected abstract void configure(I bean); -} +/* + * Copyright 2002-2008 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.beans.factory.aspectj; + +/** + * Generic-based dependency injection aspect. + * <p> + * This aspect allows users to implement efficient, type-safe dependency injection without + * the use of the @Configurable annotation. + * + * The subaspect of this aspect doesn't need to include any AOP constructs. + * For example, here is a subaspect that configures the <code>PricingStrategyClient</code> objects. + * <pre> + * aspect PricingStrategyDependencyInjectionAspect + * extends GenericInterfaceDrivenDependencyInjectionAspect<PricingStrategyClient> { + * private PricingStrategy pricingStrategy; + * + * public void configure(PricingStrategyClient bean) { + * bean.setPricingStrategy(pricingStrategy); + * } + * + * public void setPricingStrategy(PricingStrategy pricingStrategy) { + * this.pricingStrategy = pricingStrategy; + * } + * } + * </pre> + * @author Ramnivas Laddad + * @since 3.0.0 + */ +public abstract aspect GenericInterfaceDrivenDependencyInjectionAspect<I> extends AbstractInterfaceDrivenDependencyInjectionAspect { + declare parents: I implements ConfigurableObject; + + public pointcut inConfigurableBean() : within(I+); + + public final void configureBean(Object bean) { + configure((I)bean); + } + + // Unfortunately, erasure used with generics won't allow to use the same named method + protected abstract void configure(I bean); +} diff --git a/org.springframework.aspects/src/main/java/org/springframework/cache/aspectj/AbstractCacheAspect.aj b/org.springframework.aspects/src/main/java/org/springframework/cache/aspectj/AbstractCacheAspect.aj index fd58ca3fa12..ccd94725169 100644 --- a/org.springframework.aspects/src/main/java/org/springframework/cache/aspectj/AbstractCacheAspect.aj +++ b/org.springframework.aspects/src/main/java/org/springframework/cache/aspectj/AbstractCacheAspect.aj @@ -1,73 +1,73 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cache.aspectj; - -import java.lang.reflect.Method; - -import org.aspectj.lang.annotation.SuppressAjWarnings; -import org.aspectj.lang.reflect.MethodSignature; -import org.springframework.cache.interceptor.CacheAspectSupport; -import org.springframework.cache.interceptor.CacheOperationSource; - -/** - * Abstract superaspect for AspectJ cache aspects. Concrete subaspects will implement the - * {@link #cacheMethodExecution} pointcut using a strategy such as Java 5 annotations. - * - * <p>Suitable for use inside or outside the Spring IoC container. Set the - * {@link #setCacheManager cacheManager} property appropriately, allowing use of any cache - * implementation supported by Spring. - * - * <p><b>NB:</b> If a method implements an interface that is itself cache annotated, the - * relevant Spring cache definition will <i>not</i> be resolved. - * - * @author Costin Leau - * @since 3.1 - */ -public abstract aspect AbstractCacheAspect extends CacheAspectSupport { - - protected AbstractCacheAspect() { - } - - /** - * Construct object using the given caching metadata retrieval strategy. - * @param cos {@link CacheOperationSource} implementation, retrieving Spring cache - * metadata for each joinpoint. - */ - protected AbstractCacheAspect(CacheOperationSource... cos) { - setCacheOperationSources(cos); - } - - @SuppressAjWarnings("adviceDidNotMatch") - Object around(final Object cachedObject) : cacheMethodExecution(cachedObject) { - MethodSignature methodSignature = (MethodSignature) thisJoinPoint.getSignature(); - Method method = methodSignature.getMethod(); - - Invoker aspectJInvoker = new Invoker() { - public Object invoke() { - return proceed(cachedObject); - } - }; - - return execute(aspectJInvoker, thisJoinPoint.getTarget(), method, thisJoinPoint.getArgs()); - } - - /** - * Concrete subaspects must implement this pointcut, to identify cached methods. - */ - protected abstract pointcut cacheMethodExecution(Object cachedObject); - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cache.aspectj; + +import java.lang.reflect.Method; + +import org.aspectj.lang.annotation.SuppressAjWarnings; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.cache.interceptor.CacheAspectSupport; +import org.springframework.cache.interceptor.CacheOperationSource; + +/** + * Abstract superaspect for AspectJ cache aspects. Concrete subaspects will implement the + * {@link #cacheMethodExecution} pointcut using a strategy such as Java 5 annotations. + * + * <p>Suitable for use inside or outside the Spring IoC container. Set the + * {@link #setCacheManager cacheManager} property appropriately, allowing use of any cache + * implementation supported by Spring. + * + * <p><b>NB:</b> If a method implements an interface that is itself cache annotated, the + * relevant Spring cache definition will <i>not</i> be resolved. + * + * @author Costin Leau + * @since 3.1 + */ +public abstract aspect AbstractCacheAspect extends CacheAspectSupport { + + protected AbstractCacheAspect() { + } + + /** + * Construct object using the given caching metadata retrieval strategy. + * @param cos {@link CacheOperationSource} implementation, retrieving Spring cache + * metadata for each joinpoint. + */ + protected AbstractCacheAspect(CacheOperationSource... cos) { + setCacheOperationSources(cos); + } + + @SuppressAjWarnings("adviceDidNotMatch") + Object around(final Object cachedObject) : cacheMethodExecution(cachedObject) { + MethodSignature methodSignature = (MethodSignature) thisJoinPoint.getSignature(); + Method method = methodSignature.getMethod(); + + Invoker aspectJInvoker = new Invoker() { + public Object invoke() { + return proceed(cachedObject); + } + }; + + return execute(aspectJInvoker, thisJoinPoint.getTarget(), method, thisJoinPoint.getArgs()); + } + + /** + * Concrete subaspects must implement this pointcut, to identify cached methods. + */ + protected abstract pointcut cacheMethodExecution(Object cachedObject); + +} diff --git a/org.springframework.aspects/src/main/java/org/springframework/cache/aspectj/AnnotationCacheAspect.aj b/org.springframework.aspects/src/main/java/org/springframework/cache/aspectj/AnnotationCacheAspect.aj index a0581c5b630..0687b3c54c9 100644 --- a/org.springframework.aspects/src/main/java/org/springframework/cache/aspectj/AnnotationCacheAspect.aj +++ b/org.springframework.aspects/src/main/java/org/springframework/cache/aspectj/AnnotationCacheAspect.aj @@ -1,116 +1,116 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cache.aspectj; - -import org.springframework.cache.annotation.AnnotationCacheOperationSource; -import org.springframework.cache.annotation.CacheEvict; -import org.springframework.cache.annotation.CachePut; -import org.springframework.cache.annotation.Cacheable; -import org.springframework.cache.annotation.Caching; - -/** - * Concrete AspectJ cache aspect using Spring's @{@link Cacheable} annotation. - * - * <p>When using this aspect, you <i>must</i> annotate the implementation class (and/or - * methods within that class), <i>not</i> the interface (if any) that the class - * implements. AspectJ follows Java's rule that annotations on interfaces are <i>not</i> - * inherited. - * - * <p>A {@code @Cacheable} annotation on a class specifies the default caching semantics - * for the execution of any <b>public</b> operation in the class. - * - * <p>A {@code @Cacheable} annotation on a method within the class overrides the default - * caching semantics given by the class annotation (if present). Any method may be - * annotated (regardless of visibility). Annotating non-public methods directly is the - * only way to get caching demarcation for the execution of such operations. - * - * @author Costin Leau - * @since 3.1 - */ -public aspect AnnotationCacheAspect extends AbstractCacheAspect { - - public AnnotationCacheAspect() { - super(new AnnotationCacheOperationSource(false)); - } - - /** - * Matches the execution of any public method in a type with the @{@link Cacheable} - * annotation, or any subtype of a type with the {@code @Cacheable} annotation. - */ - private pointcut executionOfAnyPublicMethodInAtCacheableType() : - execution(public * ((@Cacheable *)+).*(..)) && within(@Cacheable *); - - /** - * Matches the execution of any public method in a type with the @{@link CacheEvict} - * annotation, or any subtype of a type with the {@code CacheEvict} annotation. - */ - private pointcut executionOfAnyPublicMethodInAtCacheEvictType() : - execution(public * ((@CacheEvict *)+).*(..)) && within(@CacheEvict *); - - /** - * Matches the execution of any public method in a type with the @{@link CachePut} - * annotation, or any subtype of a type with the {@code CachePut} annotation. - */ - private pointcut executionOfAnyPublicMethodInAtCachePutType() : - execution(public * ((@CachePut *)+).*(..)) && within(@CachePut *); - - /** - * Matches the execution of any public method in a type with the @{@link Caching} - * annotation, or any subtype of a type with the {@code Caching} annotation. - */ - private pointcut executionOfAnyPublicMethodInAtCachingType() : - execution(public * ((@Caching *)+).*(..)) && within(@Caching *); - - /** - * Matches the execution of any method with the @{@link Cacheable} annotation. - */ - private pointcut executionOfCacheableMethod() : - execution(@Cacheable * *(..)); - - /** - * Matches the execution of any method with the @{@link CacheEvict} annotation. - */ - private pointcut executionOfCacheEvictMethod() : - execution(@CacheEvict * *(..)); - - /** - * Matches the execution of any method with the @{@link CachePut} annotation. - */ - private pointcut executionOfCachePutMethod() : - execution(@CachePut * *(..)); - - /** - * Matches the execution of any method with the @{@link Caching} annotation. - */ - private pointcut executionOfCachingMethod() : - execution(@Caching * *(..)); - - /** - * Definition of pointcut from super aspect - matched join points will have Spring - * cache management applied. - */ - protected pointcut cacheMethodExecution(Object cachedObject) : - (executionOfAnyPublicMethodInAtCacheableType() - || executionOfAnyPublicMethodInAtCacheEvictType() - || executionOfAnyPublicMethodInAtCachePutType() - || executionOfAnyPublicMethodInAtCachingType() - || executionOfCacheableMethod() - || executionOfCacheEvictMethod() - || executionOfCachePutMethod() - || executionOfCachingMethod()) - && this(cachedObject); +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cache.aspectj; + +import org.springframework.cache.annotation.AnnotationCacheOperationSource; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.CachePut; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.cache.annotation.Caching; + +/** + * Concrete AspectJ cache aspect using Spring's @{@link Cacheable} annotation. + * + * <p>When using this aspect, you <i>must</i> annotate the implementation class (and/or + * methods within that class), <i>not</i> the interface (if any) that the class + * implements. AspectJ follows Java's rule that annotations on interfaces are <i>not</i> + * inherited. + * + * <p>A {@code @Cacheable} annotation on a class specifies the default caching semantics + * for the execution of any <b>public</b> operation in the class. + * + * <p>A {@code @Cacheable} annotation on a method within the class overrides the default + * caching semantics given by the class annotation (if present). Any method may be + * annotated (regardless of visibility). Annotating non-public methods directly is the + * only way to get caching demarcation for the execution of such operations. + * + * @author Costin Leau + * @since 3.1 + */ +public aspect AnnotationCacheAspect extends AbstractCacheAspect { + + public AnnotationCacheAspect() { + super(new AnnotationCacheOperationSource(false)); + } + + /** + * Matches the execution of any public method in a type with the @{@link Cacheable} + * annotation, or any subtype of a type with the {@code @Cacheable} annotation. + */ + private pointcut executionOfAnyPublicMethodInAtCacheableType() : + execution(public * ((@Cacheable *)+).*(..)) && within(@Cacheable *); + + /** + * Matches the execution of any public method in a type with the @{@link CacheEvict} + * annotation, or any subtype of a type with the {@code CacheEvict} annotation. + */ + private pointcut executionOfAnyPublicMethodInAtCacheEvictType() : + execution(public * ((@CacheEvict *)+).*(..)) && within(@CacheEvict *); + + /** + * Matches the execution of any public method in a type with the @{@link CachePut} + * annotation, or any subtype of a type with the {@code CachePut} annotation. + */ + private pointcut executionOfAnyPublicMethodInAtCachePutType() : + execution(public * ((@CachePut *)+).*(..)) && within(@CachePut *); + + /** + * Matches the execution of any public method in a type with the @{@link Caching} + * annotation, or any subtype of a type with the {@code Caching} annotation. + */ + private pointcut executionOfAnyPublicMethodInAtCachingType() : + execution(public * ((@Caching *)+).*(..)) && within(@Caching *); + + /** + * Matches the execution of any method with the @{@link Cacheable} annotation. + */ + private pointcut executionOfCacheableMethod() : + execution(@Cacheable * *(..)); + + /** + * Matches the execution of any method with the @{@link CacheEvict} annotation. + */ + private pointcut executionOfCacheEvictMethod() : + execution(@CacheEvict * *(..)); + + /** + * Matches the execution of any method with the @{@link CachePut} annotation. + */ + private pointcut executionOfCachePutMethod() : + execution(@CachePut * *(..)); + + /** + * Matches the execution of any method with the @{@link Caching} annotation. + */ + private pointcut executionOfCachingMethod() : + execution(@Caching * *(..)); + + /** + * Definition of pointcut from super aspect - matched join points will have Spring + * cache management applied. + */ + protected pointcut cacheMethodExecution(Object cachedObject) : + (executionOfAnyPublicMethodInAtCacheableType() + || executionOfAnyPublicMethodInAtCacheEvictType() + || executionOfAnyPublicMethodInAtCachePutType() + || executionOfAnyPublicMethodInAtCachingType() + || executionOfCacheableMethod() + || executionOfCacheEvictMethod() + || executionOfCachePutMethod() + || executionOfCachingMethod()) + && this(cachedObject); } \ No newline at end of file diff --git a/org.springframework.aspects/src/main/java/org/springframework/mock/staticmock/AbstractMethodMockingControl.aj b/org.springframework.aspects/src/main/java/org/springframework/mock/staticmock/AbstractMethodMockingControl.aj index a2c4b8acf64..6ca2bd728c6 100644 --- a/org.springframework.aspects/src/main/java/org/springframework/mock/staticmock/AbstractMethodMockingControl.aj +++ b/org.springframework.aspects/src/main/java/org/springframework/mock/staticmock/AbstractMethodMockingControl.aj @@ -1,197 +1,197 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.mock.staticmock; - -import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; - -/** - * Abstract aspect to enable mocking of methods picked out by a pointcut. - * Sub-aspects must define the mockStaticsTestMethod() pointcut to - * indicate call stacks when mocking should be triggered, and the - * methodToMock() pointcut to pick out a method invocations to mock. - * - * @author Rod Johnson - * @author Ramnivas Laddad - */ -public abstract aspect AbstractMethodMockingControl percflow(mockStaticsTestMethod()) { - - protected abstract pointcut mockStaticsTestMethod(); - - protected abstract pointcut methodToMock(); - - private boolean recording = true; - - static enum CallResponse { nothing, return_, throw_ }; - - // Represents a list of expected calls to static entity methods - // Public to allow inserted code to access: is this normal?? - public class Expectations { - - // Represents an expected call to a static entity method - private class Call { - private final String signature; - private final Object[] args; - - private Object responseObject; // return value or throwable - private CallResponse responseType = CallResponse.nothing; - - public Call(String name, Object[] args) { - this.signature = name; - this.args = args; - } - - public boolean hasResponseSpecified() { - return responseType != CallResponse.nothing; - } - - public void setReturnVal(Object retVal) { - this.responseObject = retVal; - responseType = CallResponse.return_; - } - - public void setThrow(Throwable throwable) { - this.responseObject = throwable; - responseType = CallResponse.throw_; - } - - public Object returnValue(String lastSig, Object[] args) { - checkSignature(lastSig, args); - return responseObject; - } - - public Object throwException(String lastSig, Object[] args) { - checkSignature(lastSig, args); - throw (RuntimeException)responseObject; - } - - private void checkSignature(String lastSig, Object[] args) { - if (!signature.equals(lastSig)) { - throw new IllegalArgumentException("Signature doesn't match"); - } - if (!Arrays.equals(this.args, args)) { - throw new IllegalArgumentException("Arguments don't match"); - } - } - } - - private List<Call> calls = new LinkedList<Call>(); - - // Calls already verified - private int verified; - - public void verify() { - if (verified != calls.size()) { - throw new IllegalStateException("Expected " + calls.size() - + " calls, received " + verified); - } - } - - /** - * Validate the call and provide the expected return value - * @param lastSig - * @param args - * @return - */ - public Object respond(String lastSig, Object[] args) { - Call call = nextCall(); - CallResponse responseType = call.responseType; - if (responseType == CallResponse.return_) { - return call.returnValue(lastSig, args); - } else if(responseType == CallResponse.throw_) { - return (RuntimeException)call.throwException(lastSig, args); - } else if(responseType == CallResponse.nothing) { - // do nothing - } - throw new IllegalStateException("Behavior of " + call + " not specified"); - } - - private Call nextCall() { - if (verified > calls.size() - 1) { - throw new IllegalStateException("Expected " + calls.size() - + " calls, received " + verified); - } - return calls.get(verified++); - } - - public void expectCall(String lastSig, Object lastArgs[]) { - Call call = new Call(lastSig, lastArgs); - calls.add(call); - } - - public boolean hasCalls() { - return !calls.isEmpty(); - } - - public void expectReturn(Object retVal) { - Call call = calls.get(calls.size() - 1); - if (call.hasResponseSpecified()) { - throw new IllegalStateException("No static method invoked before setting return value"); - } - call.setReturnVal(retVal); - } - - public void expectThrow(Throwable throwable) { - Call call = calls.get(calls.size() - 1); - if (call.hasResponseSpecified()) { - throw new IllegalStateException("No static method invoked before setting throwable"); - } - call.setThrow(throwable); - } - } - - private Expectations expectations = new Expectations(); - - after() returning : mockStaticsTestMethod() { - if (recording && (expectations.hasCalls())) { - throw new IllegalStateException( - "Calls recorded, yet playback state never reached: Create expectations then call " - + this.getClass().getSimpleName() + ".playback()"); - } - expectations.verify(); - } - - Object around() : methodToMock() && cflowbelow(mockStaticsTestMethod()) { - if (recording) { - expectations.expectCall(thisJoinPointStaticPart.toLongString(), thisJoinPoint.getArgs()); - // Return value doesn't matter - return null; - } else { - return expectations.respond(thisJoinPointStaticPart.toLongString(), thisJoinPoint.getArgs()); - } - } - - public void expectReturnInternal(Object retVal) { - if (!recording) { - throw new IllegalStateException("Not recording: Cannot set return value"); - } - expectations.expectReturn(retVal); - } - - public void expectThrowInternal(Throwable throwable) { - if (!recording) { - throw new IllegalStateException("Not recording: Cannot set throwable value"); - } - expectations.expectThrow(throwable); - } - - public void playbackInternal() { - recording = false; - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.mock.staticmock; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +/** + * Abstract aspect to enable mocking of methods picked out by a pointcut. + * Sub-aspects must define the mockStaticsTestMethod() pointcut to + * indicate call stacks when mocking should be triggered, and the + * methodToMock() pointcut to pick out a method invocations to mock. + * + * @author Rod Johnson + * @author Ramnivas Laddad + */ +public abstract aspect AbstractMethodMockingControl percflow(mockStaticsTestMethod()) { + + protected abstract pointcut mockStaticsTestMethod(); + + protected abstract pointcut methodToMock(); + + private boolean recording = true; + + static enum CallResponse { nothing, return_, throw_ }; + + // Represents a list of expected calls to static entity methods + // Public to allow inserted code to access: is this normal?? + public class Expectations { + + // Represents an expected call to a static entity method + private class Call { + private final String signature; + private final Object[] args; + + private Object responseObject; // return value or throwable + private CallResponse responseType = CallResponse.nothing; + + public Call(String name, Object[] args) { + this.signature = name; + this.args = args; + } + + public boolean hasResponseSpecified() { + return responseType != CallResponse.nothing; + } + + public void setReturnVal(Object retVal) { + this.responseObject = retVal; + responseType = CallResponse.return_; + } + + public void setThrow(Throwable throwable) { + this.responseObject = throwable; + responseType = CallResponse.throw_; + } + + public Object returnValue(String lastSig, Object[] args) { + checkSignature(lastSig, args); + return responseObject; + } + + public Object throwException(String lastSig, Object[] args) { + checkSignature(lastSig, args); + throw (RuntimeException)responseObject; + } + + private void checkSignature(String lastSig, Object[] args) { + if (!signature.equals(lastSig)) { + throw new IllegalArgumentException("Signature doesn't match"); + } + if (!Arrays.equals(this.args, args)) { + throw new IllegalArgumentException("Arguments don't match"); + } + } + } + + private List<Call> calls = new LinkedList<Call>(); + + // Calls already verified + private int verified; + + public void verify() { + if (verified != calls.size()) { + throw new IllegalStateException("Expected " + calls.size() + + " calls, received " + verified); + } + } + + /** + * Validate the call and provide the expected return value + * @param lastSig + * @param args + * @return + */ + public Object respond(String lastSig, Object[] args) { + Call call = nextCall(); + CallResponse responseType = call.responseType; + if (responseType == CallResponse.return_) { + return call.returnValue(lastSig, args); + } else if(responseType == CallResponse.throw_) { + return (RuntimeException)call.throwException(lastSig, args); + } else if(responseType == CallResponse.nothing) { + // do nothing + } + throw new IllegalStateException("Behavior of " + call + " not specified"); + } + + private Call nextCall() { + if (verified > calls.size() - 1) { + throw new IllegalStateException("Expected " + calls.size() + + " calls, received " + verified); + } + return calls.get(verified++); + } + + public void expectCall(String lastSig, Object lastArgs[]) { + Call call = new Call(lastSig, lastArgs); + calls.add(call); + } + + public boolean hasCalls() { + return !calls.isEmpty(); + } + + public void expectReturn(Object retVal) { + Call call = calls.get(calls.size() - 1); + if (call.hasResponseSpecified()) { + throw new IllegalStateException("No static method invoked before setting return value"); + } + call.setReturnVal(retVal); + } + + public void expectThrow(Throwable throwable) { + Call call = calls.get(calls.size() - 1); + if (call.hasResponseSpecified()) { + throw new IllegalStateException("No static method invoked before setting throwable"); + } + call.setThrow(throwable); + } + } + + private Expectations expectations = new Expectations(); + + after() returning : mockStaticsTestMethod() { + if (recording && (expectations.hasCalls())) { + throw new IllegalStateException( + "Calls recorded, yet playback state never reached: Create expectations then call " + + this.getClass().getSimpleName() + ".playback()"); + } + expectations.verify(); + } + + Object around() : methodToMock() && cflowbelow(mockStaticsTestMethod()) { + if (recording) { + expectations.expectCall(thisJoinPointStaticPart.toLongString(), thisJoinPoint.getArgs()); + // Return value doesn't matter + return null; + } else { + return expectations.respond(thisJoinPointStaticPart.toLongString(), thisJoinPoint.getArgs()); + } + } + + public void expectReturnInternal(Object retVal) { + if (!recording) { + throw new IllegalStateException("Not recording: Cannot set return value"); + } + expectations.expectReturn(retVal); + } + + public void expectThrowInternal(Throwable throwable) { + if (!recording) { + throw new IllegalStateException("Not recording: Cannot set throwable value"); + } + expectations.expectThrow(throwable); + } + + public void playbackInternal() { + recording = false; + } + +} diff --git a/org.springframework.aspects/src/main/java/org/springframework/mock/staticmock/AnnotationDrivenStaticEntityMockingControl.aj b/org.springframework.aspects/src/main/java/org/springframework/mock/staticmock/AnnotationDrivenStaticEntityMockingControl.aj index 296a1973161..1c35a47e97e 100644 --- a/org.springframework.aspects/src/main/java/org/springframework/mock/staticmock/AnnotationDrivenStaticEntityMockingControl.aj +++ b/org.springframework.aspects/src/main/java/org/springframework/mock/staticmock/AnnotationDrivenStaticEntityMockingControl.aj @@ -1,68 +1,68 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.mock.staticmock; - -/** - * Annotation-based aspect to use in test build to enable mocking static methods - * on JPA-annotated <code>@Entity</code> classes, as used by Roo for finders. - * - * <p>Mocking will occur in the call stack of any method in a class (typically a test class) - * that is annotated with the @MockStaticEntityMethods annotation. - * - * <p>Also provides static methods to simplify the programming model for - * entering playback mode and setting expected return values. - * - * <p>Usage: - * <ol> - * <li>Annotate a test class with @MockStaticEntityMethods. - * <li>In each test method, AnnotationDrivenStaticEntityMockingControl will begin in recording mode. - * Invoke static methods on Entity classes, with each recording-mode invocation - * being followed by an invocation to the static expectReturn() or expectThrow() - * method on AnnotationDrivenStaticEntityMockingControl. - * <li>Invoke the static AnnotationDrivenStaticEntityMockingControl() method. - * <li>Call the code you wish to test that uses the static methods. Verification will - * occur automatically. - * </ol> - * - * @author Rod Johnson - * @author Ramnivas Laddad - * @see MockStaticEntityMethods - */ -public aspect AnnotationDrivenStaticEntityMockingControl extends AbstractMethodMockingControl { - - /** - * Stop recording mock calls and enter playback state - */ - public static void playback() { - AnnotationDrivenStaticEntityMockingControl.aspectOf().playbackInternal(); - } - - public static void expectReturn(Object retVal) { - AnnotationDrivenStaticEntityMockingControl.aspectOf().expectReturnInternal(retVal); - } - - public static void expectThrow(Throwable throwable) { - AnnotationDrivenStaticEntityMockingControl.aspectOf().expectThrowInternal(throwable); - } - - // Only matches directly annotated @Test methods, to allow methods in - // @MockStatics classes to invoke each other without resetting the mocking environment - protected pointcut mockStaticsTestMethod() : execution(public * (@MockStaticEntityMethods *).*(..)); - - protected pointcut methodToMock() : execution(public static * (@javax.persistence.Entity *).*(..)); - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.mock.staticmock; + +/** + * Annotation-based aspect to use in test build to enable mocking static methods + * on JPA-annotated <code>@Entity</code> classes, as used by Roo for finders. + * + * <p>Mocking will occur in the call stack of any method in a class (typically a test class) + * that is annotated with the @MockStaticEntityMethods annotation. + * + * <p>Also provides static methods to simplify the programming model for + * entering playback mode and setting expected return values. + * + * <p>Usage: + * <ol> + * <li>Annotate a test class with @MockStaticEntityMethods. + * <li>In each test method, AnnotationDrivenStaticEntityMockingControl will begin in recording mode. + * Invoke static methods on Entity classes, with each recording-mode invocation + * being followed by an invocation to the static expectReturn() or expectThrow() + * method on AnnotationDrivenStaticEntityMockingControl. + * <li>Invoke the static AnnotationDrivenStaticEntityMockingControl() method. + * <li>Call the code you wish to test that uses the static methods. Verification will + * occur automatically. + * </ol> + * + * @author Rod Johnson + * @author Ramnivas Laddad + * @see MockStaticEntityMethods + */ +public aspect AnnotationDrivenStaticEntityMockingControl extends AbstractMethodMockingControl { + + /** + * Stop recording mock calls and enter playback state + */ + public static void playback() { + AnnotationDrivenStaticEntityMockingControl.aspectOf().playbackInternal(); + } + + public static void expectReturn(Object retVal) { + AnnotationDrivenStaticEntityMockingControl.aspectOf().expectReturnInternal(retVal); + } + + public static void expectThrow(Throwable throwable) { + AnnotationDrivenStaticEntityMockingControl.aspectOf().expectThrowInternal(throwable); + } + + // Only matches directly annotated @Test methods, to allow methods in + // @MockStatics classes to invoke each other without resetting the mocking environment + protected pointcut mockStaticsTestMethod() : execution(public * (@MockStaticEntityMethods *).*(..)); + + protected pointcut methodToMock() : execution(public static * (@javax.persistence.Entity *).*(..)); + +} diff --git a/org.springframework.aspects/src/main/java/org/springframework/mock/staticmock/MockStaticEntityMethods.java b/org.springframework.aspects/src/main/java/org/springframework/mock/staticmock/MockStaticEntityMethods.java index 438ad69c7c1..1216c5f1e68 100644 --- a/org.springframework.aspects/src/main/java/org/springframework/mock/staticmock/MockStaticEntityMethods.java +++ b/org.springframework.aspects/src/main/java/org/springframework/mock/staticmock/MockStaticEntityMethods.java @@ -1,34 +1,34 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.mock.staticmock; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Annotation to indicate a test class for whose @Test methods - * static methods on Entity classes should be mocked. - * - * @author Rod Johnson - * @see AbstractMethodMockingControl - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -public @interface MockStaticEntityMethods { - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.mock.staticmock; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation to indicate a test class for whose @Test methods + * static methods on Entity classes should be mocked. + * + * @author Rod Johnson + * @see AbstractMethodMockingControl + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface MockStaticEntityMethods { + +} diff --git a/org.springframework.aspects/src/main/java/org/springframework/scheduling/aspectj/AbstractAsyncExecutionAspect.aj b/org.springframework.aspects/src/main/java/org/springframework/scheduling/aspectj/AbstractAsyncExecutionAspect.aj index af070a6996c..c5402271142 100644 --- a/org.springframework.aspects/src/main/java/org/springframework/scheduling/aspectj/AbstractAsyncExecutionAspect.aj +++ b/org.springframework.aspects/src/main/java/org/springframework/scheduling/aspectj/AbstractAsyncExecutionAspect.aj @@ -1,75 +1,75 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.scheduling.aspectj; - -import java.util.concurrent.Callable; -import java.util.concurrent.Executor; -import java.util.concurrent.Future; - -import org.aspectj.lang.reflect.MethodSignature; -import org.springframework.core.task.AsyncTaskExecutor; -import org.springframework.core.task.SimpleAsyncTaskExecutor; -import org.springframework.core.task.support.TaskExecutorAdapter; - -/** - * Abstract aspect that routes selected methods asynchronously. - * - * <p>This aspect needs to be injected with an implementation of - * {@link Executor} to activate it for a specific thread pool. - * Otherwise it will simply delegate all calls synchronously. - * - * @author Ramnivas Laddad - * @author Juergen Hoeller - * @since 3.0.5 - */ -public abstract aspect AbstractAsyncExecutionAspect { - - private AsyncTaskExecutor asyncExecutor; - - public void setExecutor(Executor executor) { - if (executor instanceof AsyncTaskExecutor) { - this.asyncExecutor = (AsyncTaskExecutor) executor; - } - else { - this.asyncExecutor = new TaskExecutorAdapter(executor); - } - } - - Object around() : asyncMethod() { - if (this.asyncExecutor == null) { - return proceed(); - } - Callable<Object> callable = new Callable<Object>() { - public Object call() throws Exception { - Object result = proceed(); - if (result instanceof Future) { - return ((Future<?>) result).get(); - } - return null; - }}; - Future<?> result = this.asyncExecutor.submit(callable); - if (Future.class.isAssignableFrom(((MethodSignature) thisJoinPointStaticPart.getSignature()).getReturnType())) { - return result; - } - else { - return null; - } - } - - public abstract pointcut asyncMethod(); - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.scheduling.aspectj; + +import java.util.concurrent.Callable; +import java.util.concurrent.Executor; +import java.util.concurrent.Future; + +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.core.task.AsyncTaskExecutor; +import org.springframework.core.task.SimpleAsyncTaskExecutor; +import org.springframework.core.task.support.TaskExecutorAdapter; + +/** + * Abstract aspect that routes selected methods asynchronously. + * + * <p>This aspect needs to be injected with an implementation of + * {@link Executor} to activate it for a specific thread pool. + * Otherwise it will simply delegate all calls synchronously. + * + * @author Ramnivas Laddad + * @author Juergen Hoeller + * @since 3.0.5 + */ +public abstract aspect AbstractAsyncExecutionAspect { + + private AsyncTaskExecutor asyncExecutor; + + public void setExecutor(Executor executor) { + if (executor instanceof AsyncTaskExecutor) { + this.asyncExecutor = (AsyncTaskExecutor) executor; + } + else { + this.asyncExecutor = new TaskExecutorAdapter(executor); + } + } + + Object around() : asyncMethod() { + if (this.asyncExecutor == null) { + return proceed(); + } + Callable<Object> callable = new Callable<Object>() { + public Object call() throws Exception { + Object result = proceed(); + if (result instanceof Future) { + return ((Future<?>) result).get(); + } + return null; + }}; + Future<?> result = this.asyncExecutor.submit(callable); + if (Future.class.isAssignableFrom(((MethodSignature) thisJoinPointStaticPart.getSignature()).getReturnType())) { + return result; + } + else { + return null; + } + } + + public abstract pointcut asyncMethod(); + +} diff --git a/org.springframework.aspects/src/main/java/org/springframework/scheduling/aspectj/AnnotationAsyncExecutionAspect.aj b/org.springframework.aspects/src/main/java/org/springframework/scheduling/aspectj/AnnotationAsyncExecutionAspect.aj index ee37fd25e8a..328e742670f 100644 --- a/org.springframework.aspects/src/main/java/org/springframework/scheduling/aspectj/AnnotationAsyncExecutionAspect.aj +++ b/org.springframework.aspects/src/main/java/org/springframework/scheduling/aspectj/AnnotationAsyncExecutionAspect.aj @@ -1,54 +1,54 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.scheduling.aspectj; - -import java.util.concurrent.Future; -import org.springframework.scheduling.annotation.Async; - -/** - * Aspect to route methods based on the {@link Async} annotation. - * - * <p>This aspect routes methods marked with the {@link Async} annotation - * as well as methods in classes marked with the same. Any method expected - * to be routed asynchronously must return either void, {@link Future}, - * or a subtype of {@link Future}. This aspect, therefore, will produce - * a compile-time error for methods that violate this constraint on the return type. - * If, however, a class marked with <code>@Async</code> contains a method that - * violates this constraint, it produces only a warning. - * - * @author Ramnivas Laddad - * @since 3.0.5 - */ -public aspect AnnotationAsyncExecutionAspect extends AbstractAsyncExecutionAspect { - - private pointcut asyncMarkedMethod() - : execution(@Async (void || Future+) *(..)); - - private pointcut asyncTypeMarkedMethod() - : execution((void || Future+) (@Async *).*(..)); - - public pointcut asyncMethod() : asyncMarkedMethod() || asyncTypeMarkedMethod(); - - declare error: - execution(@Async !(void||Future) *(..)): - "Only methods that return void or Future may have an @Async annotation"; - - declare warning: - execution(!(void||Future) (@Async *).*(..)): - "Methods in a class marked with @Async that do not return void or Future will be routed synchronously"; - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.scheduling.aspectj; + +import java.util.concurrent.Future; +import org.springframework.scheduling.annotation.Async; + +/** + * Aspect to route methods based on the {@link Async} annotation. + * + * <p>This aspect routes methods marked with the {@link Async} annotation + * as well as methods in classes marked with the same. Any method expected + * to be routed asynchronously must return either void, {@link Future}, + * or a subtype of {@link Future}. This aspect, therefore, will produce + * a compile-time error for methods that violate this constraint on the return type. + * If, however, a class marked with <code>@Async</code> contains a method that + * violates this constraint, it produces only a warning. + * + * @author Ramnivas Laddad + * @since 3.0.5 + */ +public aspect AnnotationAsyncExecutionAspect extends AbstractAsyncExecutionAspect { + + private pointcut asyncMarkedMethod() + : execution(@Async (void || Future+) *(..)); + + private pointcut asyncTypeMarkedMethod() + : execution((void || Future+) (@Async *).*(..)); + + public pointcut asyncMethod() : asyncMarkedMethod() || asyncTypeMarkedMethod(); + + declare error: + execution(@Async !(void||Future) *(..)): + "Only methods that return void or Future may have an @Async annotation"; + + declare warning: + execution(!(void||Future) (@Async *).*(..)): + "Methods in a class marked with @Async that do not return void or Future will be routed synchronously"; + +} diff --git a/org.springframework.aspects/src/main/java/org/springframework/transaction/aspectj/AbstractTransactionAspect.aj b/org.springframework.aspects/src/main/java/org/springframework/transaction/aspectj/AbstractTransactionAspect.aj index 985ac62fb41..c1b23c1bcb4 100644 --- a/org.springframework.aspects/src/main/java/org/springframework/transaction/aspectj/AbstractTransactionAspect.aj +++ b/org.springframework.aspects/src/main/java/org/springframework/transaction/aspectj/AbstractTransactionAspect.aj @@ -1,93 +1,93 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.transaction.aspectj; - -import java.lang.reflect.Method; - -import org.aspectj.lang.annotation.SuppressAjWarnings; -import org.aspectj.lang.reflect.MethodSignature; -import org.springframework.transaction.interceptor.TransactionAspectSupport; -import org.springframework.transaction.interceptor.TransactionAttributeSource; - -/** - * Abstract superaspect for AspectJ transaction aspects. Concrete - * subaspects will implement the <code>transactionalMethodExecution()</code> - * pointcut using a strategy such as Java 5 annotations. - * - * <p>Suitable for use inside or outside the Spring IoC container. - * Set the "transactionManager" property appropriately, allowing - * use of any transaction implementation supported by Spring. - * - * <p><b>NB:</b> If a method implements an interface that is itself - * transactionally annotated, the relevant Spring transaction attribute - * will <i>not</i> be resolved. This behavior will vary from that of Spring AOP - * if proxying an interface (but not when proxying a class). We recommend that - * transaction annotations should be added to classes, rather than business - * interfaces, as they are an implementation detail rather than a contract - * specification validation. - * - * @author Rod Johnson - * @author Ramnivas Laddad - * @since 2.0 - */ -public abstract aspect AbstractTransactionAspect extends TransactionAspectSupport { - - /** - * Construct object using the given transaction metadata retrieval strategy. - * @param tas TransactionAttributeSource implementation, retrieving Spring - * transaction metadata for each joinpoint. Write the subclass to pass in null - * if it's intended to be configured by Setter Injection. - */ - protected AbstractTransactionAspect(TransactionAttributeSource tas) { - setTransactionAttributeSource(tas); - } - - @SuppressAjWarnings("adviceDidNotMatch") - before(Object txObject) : transactionalMethodExecution(txObject) { - MethodSignature methodSignature = (MethodSignature) thisJoinPoint.getSignature(); - Method method = methodSignature.getMethod(); - TransactionInfo txInfo = createTransactionIfNecessary(method, txObject.getClass()); - } - - @SuppressAjWarnings("adviceDidNotMatch") - after(Object txObject) throwing(Throwable t) : transactionalMethodExecution(txObject) { - try { - completeTransactionAfterThrowing(TransactionAspectSupport.currentTransactionInfo(), t); - } - catch (Throwable t2) { - logger.error("Failed to close transaction after throwing in a transactional method", t2); - } - } - - @SuppressAjWarnings("adviceDidNotMatch") - after(Object txObject) returning() : transactionalMethodExecution(txObject) { - commitTransactionAfterReturning(TransactionAspectSupport.currentTransactionInfo()); - } - - @SuppressAjWarnings("adviceDidNotMatch") - after(Object txObject) : transactionalMethodExecution(txObject) { - cleanupTransactionInfo(TransactionAspectSupport.currentTransactionInfo()); - } - - /** - * Concrete subaspects must implement this pointcut, to identify - * transactional methods. For each selected joinpoint, TransactionMetadata - * will be retrieved using Spring's TransactionAttributeSource interface. - */ - protected abstract pointcut transactionalMethodExecution(Object txObject); - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.transaction.aspectj; + +import java.lang.reflect.Method; + +import org.aspectj.lang.annotation.SuppressAjWarnings; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.transaction.interceptor.TransactionAspectSupport; +import org.springframework.transaction.interceptor.TransactionAttributeSource; + +/** + * Abstract superaspect for AspectJ transaction aspects. Concrete + * subaspects will implement the <code>transactionalMethodExecution()</code> + * pointcut using a strategy such as Java 5 annotations. + * + * <p>Suitable for use inside or outside the Spring IoC container. + * Set the "transactionManager" property appropriately, allowing + * use of any transaction implementation supported by Spring. + * + * <p><b>NB:</b> If a method implements an interface that is itself + * transactionally annotated, the relevant Spring transaction attribute + * will <i>not</i> be resolved. This behavior will vary from that of Spring AOP + * if proxying an interface (but not when proxying a class). We recommend that + * transaction annotations should be added to classes, rather than business + * interfaces, as they are an implementation detail rather than a contract + * specification validation. + * + * @author Rod Johnson + * @author Ramnivas Laddad + * @since 2.0 + */ +public abstract aspect AbstractTransactionAspect extends TransactionAspectSupport { + + /** + * Construct object using the given transaction metadata retrieval strategy. + * @param tas TransactionAttributeSource implementation, retrieving Spring + * transaction metadata for each joinpoint. Write the subclass to pass in null + * if it's intended to be configured by Setter Injection. + */ + protected AbstractTransactionAspect(TransactionAttributeSource tas) { + setTransactionAttributeSource(tas); + } + + @SuppressAjWarnings("adviceDidNotMatch") + before(Object txObject) : transactionalMethodExecution(txObject) { + MethodSignature methodSignature = (MethodSignature) thisJoinPoint.getSignature(); + Method method = methodSignature.getMethod(); + TransactionInfo txInfo = createTransactionIfNecessary(method, txObject.getClass()); + } + + @SuppressAjWarnings("adviceDidNotMatch") + after(Object txObject) throwing(Throwable t) : transactionalMethodExecution(txObject) { + try { + completeTransactionAfterThrowing(TransactionAspectSupport.currentTransactionInfo(), t); + } + catch (Throwable t2) { + logger.error("Failed to close transaction after throwing in a transactional method", t2); + } + } + + @SuppressAjWarnings("adviceDidNotMatch") + after(Object txObject) returning() : transactionalMethodExecution(txObject) { + commitTransactionAfterReturning(TransactionAspectSupport.currentTransactionInfo()); + } + + @SuppressAjWarnings("adviceDidNotMatch") + after(Object txObject) : transactionalMethodExecution(txObject) { + cleanupTransactionInfo(TransactionAspectSupport.currentTransactionInfo()); + } + + /** + * Concrete subaspects must implement this pointcut, to identify + * transactional methods. For each selected joinpoint, TransactionMetadata + * will be retrieved using Spring's TransactionAttributeSource interface. + */ + protected abstract pointcut transactionalMethodExecution(Object txObject); + +} diff --git a/org.springframework.aspects/src/main/java/org/springframework/transaction/aspectj/AnnotationTransactionAspect.aj b/org.springframework.aspects/src/main/java/org/springframework/transaction/aspectj/AnnotationTransactionAspect.aj index 825b7a489c3..f4b31090348 100644 --- a/org.springframework.aspects/src/main/java/org/springframework/transaction/aspectj/AnnotationTransactionAspect.aj +++ b/org.springframework.aspects/src/main/java/org/springframework/transaction/aspectj/AnnotationTransactionAspect.aj @@ -1,75 +1,75 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.transaction.aspectj; - -import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource; -import org.springframework.transaction.annotation.Transactional; - -/** - * Concrete AspectJ transaction aspect using Spring's @Transactional annotation. - * - * <p>When using this aspect, you <i>must</i> annotate the implementation class - * (and/or methods within that class), <i>not</i> the interface (if any) that - * the class implements. AspectJ follows Java's rule that annotations on - * interfaces are <i>not</i> inherited. - * - * <p>An @Transactional annotation on a class specifies the default transaction - * semantics for the execution of any <b>public</b> operation in the class. - * - * <p>An @Transactional annotation on a method within the class overrides the - * default transaction semantics given by the class annotation (if present). - * Any method may be annotated (regardless of visibility). - * Annotating non-public methods directly is the only way - * to get transaction demarcation for the execution of such operations. - * - * @author Rod Johnson - * @author Ramnivas Laddad - * @author Adrian Colyer - * @since 2.0 - * @see org.springframework.transaction.annotation.Transactional - */ -public aspect AnnotationTransactionAspect extends AbstractTransactionAspect { - - public AnnotationTransactionAspect() { - super(new AnnotationTransactionAttributeSource(false)); - } - - /** - * Matches the execution of any public method in a type with the - * Transactional annotation, or any subtype of a type with the - * Transactional annotation. - */ - private pointcut executionOfAnyPublicMethodInAtTransactionalType() : - execution(public * ((@Transactional *)+).*(..)) && within(@Transactional *); - - /** - * Matches the execution of any method with the - * Transactional annotation. - */ - private pointcut executionOfTransactionalMethod() : - execution(@Transactional * *(..)); - - /** - * Definition of pointcut from super aspect - matched join points - * will have Spring transaction management applied. - */ - protected pointcut transactionalMethodExecution(Object txObject) : - (executionOfAnyPublicMethodInAtTransactionalType() - || executionOfTransactionalMethod() ) - && this(txObject); - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.transaction.aspectj; + +import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource; +import org.springframework.transaction.annotation.Transactional; + +/** + * Concrete AspectJ transaction aspect using Spring's @Transactional annotation. + * + * <p>When using this aspect, you <i>must</i> annotate the implementation class + * (and/or methods within that class), <i>not</i> the interface (if any) that + * the class implements. AspectJ follows Java's rule that annotations on + * interfaces are <i>not</i> inherited. + * + * <p>An @Transactional annotation on a class specifies the default transaction + * semantics for the execution of any <b>public</b> operation in the class. + * + * <p>An @Transactional annotation on a method within the class overrides the + * default transaction semantics given by the class annotation (if present). + * Any method may be annotated (regardless of visibility). + * Annotating non-public methods directly is the only way + * to get transaction demarcation for the execution of such operations. + * + * @author Rod Johnson + * @author Ramnivas Laddad + * @author Adrian Colyer + * @since 2.0 + * @see org.springframework.transaction.annotation.Transactional + */ +public aspect AnnotationTransactionAspect extends AbstractTransactionAspect { + + public AnnotationTransactionAspect() { + super(new AnnotationTransactionAttributeSource(false)); + } + + /** + * Matches the execution of any public method in a type with the + * Transactional annotation, or any subtype of a type with the + * Transactional annotation. + */ + private pointcut executionOfAnyPublicMethodInAtTransactionalType() : + execution(public * ((@Transactional *)+).*(..)) && within(@Transactional *); + + /** + * Matches the execution of any method with the + * Transactional annotation. + */ + private pointcut executionOfTransactionalMethod() : + execution(@Transactional * *(..)); + + /** + * Definition of pointcut from super aspect - matched join points + * will have Spring transaction management applied. + */ + protected pointcut transactionalMethodExecution(Object txObject) : + (executionOfAnyPublicMethodInAtTransactionalType() + || executionOfTransactionalMethod() ) + && this(txObject); + +} diff --git a/org.springframework.aspects/src/test/java/org/springframework/aop/aspectj/autoproxy/AutoProxyWithCodeStyleAspectsTests.java b/org.springframework.aspects/src/test/java/org/springframework/aop/aspectj/autoproxy/AutoProxyWithCodeStyleAspectsTests.java index d593e1d1182..2dd6faa417a 100644 --- a/org.springframework.aspects/src/test/java/org/springframework/aop/aspectj/autoproxy/AutoProxyWithCodeStyleAspectsTests.java +++ b/org.springframework.aspects/src/test/java/org/springframework/aop/aspectj/autoproxy/AutoProxyWithCodeStyleAspectsTests.java @@ -1,32 +1,32 @@ -/* - * Copyright 2002-2007 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.aop.aspectj.autoproxy; - -import org.springframework.context.support.ClassPathXmlApplicationContext; - -import junit.framework.TestCase; - -/** - * @author Adrian Colyer - */ -public class AutoProxyWithCodeStyleAspectsTests extends TestCase { - - public void testNoAutoproxyingOfAjcCompiledAspects() { - new ClassPathXmlApplicationContext("org/springframework/aop/aspectj/autoproxy/ajcAutoproxyTests.xml"); - } - -} +/* + * Copyright 2002-2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.aop.aspectj.autoproxy; + +import org.springframework.context.support.ClassPathXmlApplicationContext; + +import junit.framework.TestCase; + +/** + * @author Adrian Colyer + */ +public class AutoProxyWithCodeStyleAspectsTests extends TestCase { + + public void testNoAutoproxyingOfAjcCompiledAspects() { + new ClassPathXmlApplicationContext("org/springframework/aop/aspectj/autoproxy/ajcAutoproxyTests.xml"); + } + +} diff --git a/org.springframework.aspects/src/test/java/org/springframework/aop/aspectj/autoproxy/CodeStyleAspect.aj b/org.springframework.aspects/src/test/java/org/springframework/aop/aspectj/autoproxy/CodeStyleAspect.aj index f1038fe9bd6..374bc00909a 100644 --- a/org.springframework.aspects/src/test/java/org/springframework/aop/aspectj/autoproxy/CodeStyleAspect.aj +++ b/org.springframework.aspects/src/test/java/org/springframework/aop/aspectj/autoproxy/CodeStyleAspect.aj @@ -1,36 +1,36 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.aop.aspectj.autoproxy; - -/** - * @author Adrian Colyer - */ -public aspect CodeStyleAspect { - - private String foo; - - pointcut somePC() : call(* someMethod()); - - before() : somePC() { - System.out.println("match"); - } - - public void setFoo(String foo) { - this.foo = foo; - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.aop.aspectj.autoproxy; + +/** + * @author Adrian Colyer + */ +public aspect CodeStyleAspect { + + private String foo; + + pointcut somePC() : call(* someMethod()); + + before() : somePC() { + System.out.println("match"); + } + + public void setFoo(String foo) { + this.foo = foo; + } + +} diff --git a/org.springframework.aspects/src/test/java/org/springframework/beans/factory/aspectj/SpringConfiguredWithAutoProxyingTests.java b/org.springframework.aspects/src/test/java/org/springframework/beans/factory/aspectj/SpringConfiguredWithAutoProxyingTests.java index aa8aef07a1d..16e2522d934 100644 --- a/org.springframework.aspects/src/test/java/org/springframework/beans/factory/aspectj/SpringConfiguredWithAutoProxyingTests.java +++ b/org.springframework.aspects/src/test/java/org/springframework/beans/factory/aspectj/SpringConfiguredWithAutoProxyingTests.java @@ -1,33 +1,33 @@ -/* - * Copyright 2002-2006 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.beans.factory.aspectj; - -import org.springframework.context.support.ClassPathXmlApplicationContext; - -import junit.framework.TestCase; - -public class SpringConfiguredWithAutoProxyingTests extends TestCase { - - @Override - protected void setUp() throws Exception { - new ClassPathXmlApplicationContext("org/springframework/beans/factory/aspectj/springConfigured.xml"); - } - - public void testSpringConfiguredAndAutoProxyUsedTogether() { - ; // set up is sufficient to trigger failure if this is going to fail... - } +/* + * Copyright 2002-2006 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.factory.aspectj; + +import org.springframework.context.support.ClassPathXmlApplicationContext; + +import junit.framework.TestCase; + +public class SpringConfiguredWithAutoProxyingTests extends TestCase { + + @Override + protected void setUp() throws Exception { + new ClassPathXmlApplicationContext("org/springframework/beans/factory/aspectj/springConfigured.xml"); + } + + public void testSpringConfiguredAndAutoProxyUsedTogether() { + ; // set up is sufficient to trigger failure if this is going to fail... + } } \ No newline at end of file diff --git a/org.springframework.aspects/src/test/java/org/springframework/cache/aspectj/AbstractAnnotationTest.java b/org.springframework.aspects/src/test/java/org/springframework/cache/aspectj/AbstractAnnotationTest.java index e30127e516b..b3f9d4937b7 100644 --- a/org.springframework.aspects/src/test/java/org/springframework/cache/aspectj/AbstractAnnotationTest.java +++ b/org.springframework.aspects/src/test/java/org/springframework/cache/aspectj/AbstractAnnotationTest.java @@ -1,596 +1,596 @@ -/* - * Copyright 2010-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cache.aspectj; - -import static org.junit.Assert.*; - -import java.util.Collection; -import java.util.UUID; - -import org.junit.Before; -import org.junit.Test; -import org.springframework.cache.Cache; -import org.springframework.cache.CacheManager; -import org.springframework.cache.config.AnnotatedClassCacheableService; -import org.springframework.cache.config.CacheableService; -import org.springframework.context.ApplicationContext; - -/** - * Abstract annotation test (containing several reusable methods). - * - * @author Costin Leau - * @author Chris Beams - */ -public abstract class AbstractAnnotationTest { - - protected ApplicationContext ctx; - - protected CacheableService<?> cs; - - protected CacheableService<?> ccs; - - protected CacheManager cm; - - /** @return a refreshed application context */ - protected abstract ApplicationContext getApplicationContext(); - - @Before - public void setup() { - ctx = getApplicationContext(); - cs = ctx.getBean("service", CacheableService.class); - ccs = ctx.getBean("classService", CacheableService.class); - cm = ctx.getBean(CacheManager.class); - Collection<String> cn = cm.getCacheNames(); - assertTrue(cn.contains("default")); - } - - public void testCacheable(CacheableService<?> service) throws Exception { - Object o1 = new Object(); - - Object r1 = service.cache(o1); - Object r2 = service.cache(o1); - Object r3 = service.cache(o1); - - assertSame(r1, r2); - assertSame(r1, r3); - } - - public void testEvict(CacheableService<?> service) throws Exception { - Object o1 = new Object(); - - Object r1 = service.cache(o1); - Object r2 = service.cache(o1); - - assertSame(r1, r2); - service.invalidate(o1); - Object r3 = service.cache(o1); - Object r4 = service.cache(o1); - assertNotSame(r1, r3); - assertSame(r3, r4); - } - - public void testEvictEarly(CacheableService<?> service) throws Exception { - Object o1 = new Object(); - - Object r1 = service.cache(o1); - Object r2 = service.cache(o1); - - assertSame(r1, r2); - try { - service.evictEarly(o1); - } catch (RuntimeException ex) { - // expected - } - - Object r3 = service.cache(o1); - Object r4 = service.cache(o1); - assertNotSame(r1, r3); - assertSame(r3, r4); - } - - public void testEvictException(CacheableService<?> service) throws Exception { - Object o1 = new Object(); - - Object r1 = service.cache(o1); - Object r2 = service.cache(o1); - - assertSame(r1, r2); - try { - service.evictWithException(o1); - } catch (RuntimeException ex) { - // expected - } - // exception occurred, eviction skipped, data should still be in the cache - Object r3 = service.cache(o1); - assertSame(r1, r3); - } - - public void testEvictWKey(CacheableService<?> service) throws Exception { - Object o1 = new Object(); - - Object r1 = service.cache(o1); - Object r2 = service.cache(o1); - - assertSame(r1, r2); - service.evict(o1, null); - Object r3 = service.cache(o1); - Object r4 = service.cache(o1); - assertNotSame(r1, r3); - assertSame(r3, r4); - } - - public void testEvictWKeyEarly(CacheableService<?> service) throws Exception { - Object o1 = new Object(); - - Object r1 = service.cache(o1); - Object r2 = service.cache(o1); - - assertSame(r1, r2); - - try { - service.invalidateEarly(o1, null); - } catch (Exception ex) { - // expected - } - Object r3 = service.cache(o1); - Object r4 = service.cache(o1); - assertNotSame(r1, r3); - assertSame(r3, r4); - } - - public void testEvictAll(CacheableService<?> service) throws Exception { - Object o1 = new Object(); - - Object r1 = service.cache(o1); - Object r2 = service.cache(o1); - - Object o2 = new Object(); - Object r10 = service.cache(o2); - - assertSame(r1, r2); - assertNotSame(r1, r10); - service.evictAll(new Object()); - Cache cache = cm.getCache("default"); - assertNull(cache.get(o1)); - assertNull(cache.get(o2)); - - Object r3 = service.cache(o1); - Object r4 = service.cache(o1); - assertNotSame(r1, r3); - assertSame(r3, r4); - } - - public void testConditionalExpression(CacheableService<?> service) throws Exception { - Object r1 = service.conditional(4); - Object r2 = service.conditional(4); - - assertNotSame(r1, r2); - - Object r3 = service.conditional(3); - Object r4 = service.conditional(3); - - assertSame(r3, r4); - } - - public void testKeyExpression(CacheableService<?> service) throws Exception { - Object r1 = service.key(5, 1); - Object r2 = service.key(5, 2); - - assertSame(r1, r2); - - Object r3 = service.key(1, 5); - Object r4 = service.key(2, 5); - - assertNotSame(r3, r4); - } - - public void testNullValue(CacheableService<?> service) throws Exception { - Object key = new Object(); - assertNull(service.nullValue(key)); - int nr = service.nullInvocations().intValue(); - assertNull(service.nullValue(key)); - assertEquals(nr, service.nullInvocations().intValue()); - assertNull(service.nullValue(new Object())); - assertEquals(nr + 1, service.nullInvocations().intValue()); - } - - public void testMethodName(CacheableService<?> service, String keyName) throws Exception { - Object key = new Object(); - Object r1 = service.name(key); - assertSame(r1, service.name(key)); - Cache cache = cm.getCache("default"); - // assert the method name is used - assertNotNull(cache.get(keyName)); - } - - public void testCheckedThrowable(CacheableService<?> service) throws Exception { - String arg = UUID.randomUUID().toString(); - try { - service.throwChecked(arg); - fail("Excepted exception"); - } catch (Exception ex) { - assertEquals(arg, ex.getMessage()); - } - } - - public void testUncheckedThrowable(CacheableService<?> service) throws Exception { - try { - service.throwUnchecked(Long.valueOf(1)); - fail("Excepted exception"); - } catch (RuntimeException ex) { - assertTrue("Excepted different exception type and got " + ex.getClass(), - ex instanceof UnsupportedOperationException); - // expected - } - } - - public void testNullArg(CacheableService<?> service) { - Object r1 = service.cache(null); - assertSame(r1, service.cache(null)); - } - - public void testCacheUpdate(CacheableService<?> service) { - Object o = new Object(); - Cache cache = cm.getCache("default"); - assertNull(cache.get(o)); - Object r1 = service.update(o); - assertSame(r1, cache.get(o).get()); - - o = new Object(); - assertNull(cache.get(o)); - Object r2 = service.update(o); - assertSame(r2, cache.get(o).get()); - } - - public void testConditionalCacheUpdate(CacheableService<?> service) { - Integer one = Integer.valueOf(1); - Integer three = Integer.valueOf(3); - - Cache cache = cm.getCache("default"); - assertEquals(one, Integer.valueOf(service.conditionalUpdate(one).toString())); - assertNull(cache.get(one)); - - assertEquals(three, Integer.valueOf(service.conditionalUpdate(three).toString())); - assertEquals(three, Integer.valueOf(cache.get(three).get().toString())); - } - - public void testMultiCache(CacheableService<?> service) { - Object o1 = new Object(); - Object o2 = new Object(); - - Cache primary = cm.getCache("primary"); - Cache secondary = cm.getCache("secondary"); - - assertNull(primary.get(o1)); - assertNull(secondary.get(o1)); - Object r1 = service.multiCache(o1); - assertSame(r1, primary.get(o1).get()); - assertSame(r1, secondary.get(o1).get()); - - Object r2 = service.multiCache(o1); - Object r3 = service.multiCache(o1); - - assertSame(r1, r2); - assertSame(r1, r3); - - assertNull(primary.get(o2)); - assertNull(secondary.get(o2)); - Object r4 = service.multiCache(o2); - assertSame(r4, primary.get(o2).get()); - assertSame(r4, secondary.get(o2).get()); - } - - public void testMultiEvict(CacheableService<?> service) { - Object o1 = new Object(); - - Object r1 = service.multiCache(o1); - Object r2 = service.multiCache(o1); - - Cache primary = cm.getCache("primary"); - Cache secondary = cm.getCache("secondary"); - - assertSame(r1, r2); - assertSame(r1, primary.get(o1).get()); - assertSame(r1, secondary.get(o1).get()); - - service.multiEvict(o1); - assertNull(primary.get(o1)); - assertNull(secondary.get(o1)); - - Object r3 = service.multiCache(o1); - Object r4 = service.multiCache(o1); - assertNotSame(r1, r3); - assertSame(r3, r4); - - assertSame(r3, primary.get(o1).get()); - assertSame(r4, secondary.get(o1).get()); - } - - public void testMultiPut(CacheableService<?> service) { - Object o = Integer.valueOf(1); - - Cache primary = cm.getCache("primary"); - Cache secondary = cm.getCache("secondary"); - - assertNull(primary.get(o)); - assertNull(secondary.get(o)); - Object r1 = service.multiUpdate(o); - assertSame(r1, primary.get(o).get()); - assertSame(r1, secondary.get(o).get()); - - o = Integer.valueOf(2); - assertNull(primary.get(o)); - assertNull(secondary.get(o)); - Object r2 = service.multiUpdate(o); - assertSame(r2, primary.get(o).get()); - assertSame(r2, secondary.get(o).get()); - } - - public void testMultiCacheAndEvict(CacheableService<?> service) { - String methodName = "multiCacheAndEvict"; - - Cache primary = cm.getCache("primary"); - Cache secondary = cm.getCache("secondary"); - Object key = Integer.valueOf(1); - - secondary.put(key, key); - - assertNull(secondary.get(methodName)); - assertSame(key, secondary.get(key).get()); - - Object r1 = service.multiCacheAndEvict(key); - assertSame(r1, service.multiCacheAndEvict(key)); - - // assert the method name is used - assertSame(r1, primary.get(methodName).get()); - assertNull(secondary.get(methodName)); - assertNull(secondary.get(key)); - } - - public void testMultiConditionalCacheAndEvict(CacheableService<?> service) { - Cache primary = cm.getCache("primary"); - Cache secondary = cm.getCache("secondary"); - Object key = Integer.valueOf(1); - - secondary.put(key, key); - - assertNull(primary.get(key)); - assertSame(key, secondary.get(key).get()); - - Object r1 = service.multiConditionalCacheAndEvict(key); - Object r3 = service.multiConditionalCacheAndEvict(key); - - assertTrue(!r1.equals(r3)); - assertNull(primary.get(key)); - - Object key2 = Integer.valueOf(3); - Object r2 = service.multiConditionalCacheAndEvict(key2); - assertSame(r2, service.multiConditionalCacheAndEvict(key2)); - - // assert the method name is used - assertSame(r2, primary.get(key2).get()); - assertNull(secondary.get(key2)); - } - - @Test - public void testCacheable() throws Exception { - testCacheable(cs); - } - - @Test - public void testInvalidate() throws Exception { - testEvict(cs); - } - - @Test - public void testEarlyInvalidate() throws Exception { - testEvictEarly(cs); - } - - @Test - public void testEvictWithException() throws Exception { - testEvictException(cs); - } - - @Test - public void testEvictAll() throws Exception { - testEvictAll(cs); - } - - @Test - public void testInvalidateWithKey() throws Exception { - testEvictWKey(cs); - } - - @Test - public void testEarlyInvalidateWithKey() throws Exception { - testEvictWKeyEarly(cs); - } - - @Test - public void testConditionalExpression() throws Exception { - testConditionalExpression(cs); - } - - @Test - public void testKeyExpression() throws Exception { - testKeyExpression(cs); - } - - @Test - public void testClassCacheCacheable() throws Exception { - testCacheable(ccs); - } - - @Test - public void testClassCacheInvalidate() throws Exception { - testEvict(ccs); - } - - @Test - public void testClassEarlyInvalidate() throws Exception { - testEvictEarly(ccs); - } - - @Test - public void testClassEvictAll() throws Exception { - testEvictAll(ccs); - } - - @Test - public void testClassEvictWithException() throws Exception { - testEvictException(ccs); - } - - @Test - public void testClassCacheInvalidateWKey() throws Exception { - testEvictWKey(ccs); - } - - @Test - public void testClassEarlyInvalidateWithKey() throws Exception { - testEvictWKeyEarly(ccs); - } - - @Test - public void testNullValue() throws Exception { - testNullValue(cs); - } - - @Test - public void testClassNullValue() throws Exception { - Object key = new Object(); - assertNull(ccs.nullValue(key)); - int nr = ccs.nullInvocations().intValue(); - assertNull(ccs.nullValue(key)); - assertEquals(nr, ccs.nullInvocations().intValue()); - assertNull(ccs.nullValue(new Object())); - // the check method is also cached - assertEquals(nr, ccs.nullInvocations().intValue()); - assertEquals(nr + 1, AnnotatedClassCacheableService.nullInvocations.intValue()); - } - - @Test - public void testMethodName() throws Exception { - testMethodName(cs, "name"); - } - - @Test - public void testClassMethodName() throws Exception { - testMethodName(ccs, "namedefault"); - } - - @Test - public void testNullArg() throws Exception { - testNullArg(cs); - } - - @Test - public void testClassNullArg() throws Exception { - testNullArg(ccs); - } - - @Test - public void testCheckedException() throws Exception { - testCheckedThrowable(cs); - } - - @Test - public void testClassCheckedException() throws Exception { - testCheckedThrowable(ccs); - } - - @Test - public void testUncheckedException() throws Exception { - testUncheckedThrowable(cs); - } - - @Test - public void testClassUncheckedException() throws Exception { - testUncheckedThrowable(ccs); - } - - @Test - public void testUpdate() { - testCacheUpdate(cs); - } - - @Test - public void testClassUpdate() { - testCacheUpdate(ccs); - } - - @Test - public void testConditionalUpdate() { - testConditionalCacheUpdate(cs); - } - - @Test - public void testClassConditionalUpdate() { - testConditionalCacheUpdate(ccs); - } - - @Test - public void testMultiCache() { - testMultiCache(cs); - } - - @Test - public void testClassMultiCache() { - testMultiCache(ccs); - } - - @Test - public void testMultiEvict() { - testMultiEvict(cs); - } - - @Test - public void testClassMultiEvict() { - testMultiEvict(ccs); - } - - @Test - public void testMultiPut() { - testMultiPut(cs); - } - - @Test - public void testClassMultiPut() { - testMultiPut(ccs); - } - - @Test - public void testMultiCacheAndEvict() { - testMultiCacheAndEvict(cs); - } - - @Test - public void testClassMultiCacheAndEvict() { - testMultiCacheAndEvict(ccs); - } - - @Test - public void testMultiConditionalCacheAndEvict() { - testMultiConditionalCacheAndEvict(cs); - } - - @Test - public void testClassMultiConditionalCacheAndEvict() { - testMultiConditionalCacheAndEvict(ccs); - } +/* + * Copyright 2010-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cache.aspectj; + +import static org.junit.Assert.*; + +import java.util.Collection; +import java.util.UUID; + +import org.junit.Before; +import org.junit.Test; +import org.springframework.cache.Cache; +import org.springframework.cache.CacheManager; +import org.springframework.cache.config.AnnotatedClassCacheableService; +import org.springframework.cache.config.CacheableService; +import org.springframework.context.ApplicationContext; + +/** + * Abstract annotation test (containing several reusable methods). + * + * @author Costin Leau + * @author Chris Beams + */ +public abstract class AbstractAnnotationTest { + + protected ApplicationContext ctx; + + protected CacheableService<?> cs; + + protected CacheableService<?> ccs; + + protected CacheManager cm; + + /** @return a refreshed application context */ + protected abstract ApplicationContext getApplicationContext(); + + @Before + public void setup() { + ctx = getApplicationContext(); + cs = ctx.getBean("service", CacheableService.class); + ccs = ctx.getBean("classService", CacheableService.class); + cm = ctx.getBean(CacheManager.class); + Collection<String> cn = cm.getCacheNames(); + assertTrue(cn.contains("default")); + } + + public void testCacheable(CacheableService<?> service) throws Exception { + Object o1 = new Object(); + + Object r1 = service.cache(o1); + Object r2 = service.cache(o1); + Object r3 = service.cache(o1); + + assertSame(r1, r2); + assertSame(r1, r3); + } + + public void testEvict(CacheableService<?> service) throws Exception { + Object o1 = new Object(); + + Object r1 = service.cache(o1); + Object r2 = service.cache(o1); + + assertSame(r1, r2); + service.invalidate(o1); + Object r3 = service.cache(o1); + Object r4 = service.cache(o1); + assertNotSame(r1, r3); + assertSame(r3, r4); + } + + public void testEvictEarly(CacheableService<?> service) throws Exception { + Object o1 = new Object(); + + Object r1 = service.cache(o1); + Object r2 = service.cache(o1); + + assertSame(r1, r2); + try { + service.evictEarly(o1); + } catch (RuntimeException ex) { + // expected + } + + Object r3 = service.cache(o1); + Object r4 = service.cache(o1); + assertNotSame(r1, r3); + assertSame(r3, r4); + } + + public void testEvictException(CacheableService<?> service) throws Exception { + Object o1 = new Object(); + + Object r1 = service.cache(o1); + Object r2 = service.cache(o1); + + assertSame(r1, r2); + try { + service.evictWithException(o1); + } catch (RuntimeException ex) { + // expected + } + // exception occurred, eviction skipped, data should still be in the cache + Object r3 = service.cache(o1); + assertSame(r1, r3); + } + + public void testEvictWKey(CacheableService<?> service) throws Exception { + Object o1 = new Object(); + + Object r1 = service.cache(o1); + Object r2 = service.cache(o1); + + assertSame(r1, r2); + service.evict(o1, null); + Object r3 = service.cache(o1); + Object r4 = service.cache(o1); + assertNotSame(r1, r3); + assertSame(r3, r4); + } + + public void testEvictWKeyEarly(CacheableService<?> service) throws Exception { + Object o1 = new Object(); + + Object r1 = service.cache(o1); + Object r2 = service.cache(o1); + + assertSame(r1, r2); + + try { + service.invalidateEarly(o1, null); + } catch (Exception ex) { + // expected + } + Object r3 = service.cache(o1); + Object r4 = service.cache(o1); + assertNotSame(r1, r3); + assertSame(r3, r4); + } + + public void testEvictAll(CacheableService<?> service) throws Exception { + Object o1 = new Object(); + + Object r1 = service.cache(o1); + Object r2 = service.cache(o1); + + Object o2 = new Object(); + Object r10 = service.cache(o2); + + assertSame(r1, r2); + assertNotSame(r1, r10); + service.evictAll(new Object()); + Cache cache = cm.getCache("default"); + assertNull(cache.get(o1)); + assertNull(cache.get(o2)); + + Object r3 = service.cache(o1); + Object r4 = service.cache(o1); + assertNotSame(r1, r3); + assertSame(r3, r4); + } + + public void testConditionalExpression(CacheableService<?> service) throws Exception { + Object r1 = service.conditional(4); + Object r2 = service.conditional(4); + + assertNotSame(r1, r2); + + Object r3 = service.conditional(3); + Object r4 = service.conditional(3); + + assertSame(r3, r4); + } + + public void testKeyExpression(CacheableService<?> service) throws Exception { + Object r1 = service.key(5, 1); + Object r2 = service.key(5, 2); + + assertSame(r1, r2); + + Object r3 = service.key(1, 5); + Object r4 = service.key(2, 5); + + assertNotSame(r3, r4); + } + + public void testNullValue(CacheableService<?> service) throws Exception { + Object key = new Object(); + assertNull(service.nullValue(key)); + int nr = service.nullInvocations().intValue(); + assertNull(service.nullValue(key)); + assertEquals(nr, service.nullInvocations().intValue()); + assertNull(service.nullValue(new Object())); + assertEquals(nr + 1, service.nullInvocations().intValue()); + } + + public void testMethodName(CacheableService<?> service, String keyName) throws Exception { + Object key = new Object(); + Object r1 = service.name(key); + assertSame(r1, service.name(key)); + Cache cache = cm.getCache("default"); + // assert the method name is used + assertNotNull(cache.get(keyName)); + } + + public void testCheckedThrowable(CacheableService<?> service) throws Exception { + String arg = UUID.randomUUID().toString(); + try { + service.throwChecked(arg); + fail("Excepted exception"); + } catch (Exception ex) { + assertEquals(arg, ex.getMessage()); + } + } + + public void testUncheckedThrowable(CacheableService<?> service) throws Exception { + try { + service.throwUnchecked(Long.valueOf(1)); + fail("Excepted exception"); + } catch (RuntimeException ex) { + assertTrue("Excepted different exception type and got " + ex.getClass(), + ex instanceof UnsupportedOperationException); + // expected + } + } + + public void testNullArg(CacheableService<?> service) { + Object r1 = service.cache(null); + assertSame(r1, service.cache(null)); + } + + public void testCacheUpdate(CacheableService<?> service) { + Object o = new Object(); + Cache cache = cm.getCache("default"); + assertNull(cache.get(o)); + Object r1 = service.update(o); + assertSame(r1, cache.get(o).get()); + + o = new Object(); + assertNull(cache.get(o)); + Object r2 = service.update(o); + assertSame(r2, cache.get(o).get()); + } + + public void testConditionalCacheUpdate(CacheableService<?> service) { + Integer one = Integer.valueOf(1); + Integer three = Integer.valueOf(3); + + Cache cache = cm.getCache("default"); + assertEquals(one, Integer.valueOf(service.conditionalUpdate(one).toString())); + assertNull(cache.get(one)); + + assertEquals(three, Integer.valueOf(service.conditionalUpdate(three).toString())); + assertEquals(three, Integer.valueOf(cache.get(three).get().toString())); + } + + public void testMultiCache(CacheableService<?> service) { + Object o1 = new Object(); + Object o2 = new Object(); + + Cache primary = cm.getCache("primary"); + Cache secondary = cm.getCache("secondary"); + + assertNull(primary.get(o1)); + assertNull(secondary.get(o1)); + Object r1 = service.multiCache(o1); + assertSame(r1, primary.get(o1).get()); + assertSame(r1, secondary.get(o1).get()); + + Object r2 = service.multiCache(o1); + Object r3 = service.multiCache(o1); + + assertSame(r1, r2); + assertSame(r1, r3); + + assertNull(primary.get(o2)); + assertNull(secondary.get(o2)); + Object r4 = service.multiCache(o2); + assertSame(r4, primary.get(o2).get()); + assertSame(r4, secondary.get(o2).get()); + } + + public void testMultiEvict(CacheableService<?> service) { + Object o1 = new Object(); + + Object r1 = service.multiCache(o1); + Object r2 = service.multiCache(o1); + + Cache primary = cm.getCache("primary"); + Cache secondary = cm.getCache("secondary"); + + assertSame(r1, r2); + assertSame(r1, primary.get(o1).get()); + assertSame(r1, secondary.get(o1).get()); + + service.multiEvict(o1); + assertNull(primary.get(o1)); + assertNull(secondary.get(o1)); + + Object r3 = service.multiCache(o1); + Object r4 = service.multiCache(o1); + assertNotSame(r1, r3); + assertSame(r3, r4); + + assertSame(r3, primary.get(o1).get()); + assertSame(r4, secondary.get(o1).get()); + } + + public void testMultiPut(CacheableService<?> service) { + Object o = Integer.valueOf(1); + + Cache primary = cm.getCache("primary"); + Cache secondary = cm.getCache("secondary"); + + assertNull(primary.get(o)); + assertNull(secondary.get(o)); + Object r1 = service.multiUpdate(o); + assertSame(r1, primary.get(o).get()); + assertSame(r1, secondary.get(o).get()); + + o = Integer.valueOf(2); + assertNull(primary.get(o)); + assertNull(secondary.get(o)); + Object r2 = service.multiUpdate(o); + assertSame(r2, primary.get(o).get()); + assertSame(r2, secondary.get(o).get()); + } + + public void testMultiCacheAndEvict(CacheableService<?> service) { + String methodName = "multiCacheAndEvict"; + + Cache primary = cm.getCache("primary"); + Cache secondary = cm.getCache("secondary"); + Object key = Integer.valueOf(1); + + secondary.put(key, key); + + assertNull(secondary.get(methodName)); + assertSame(key, secondary.get(key).get()); + + Object r1 = service.multiCacheAndEvict(key); + assertSame(r1, service.multiCacheAndEvict(key)); + + // assert the method name is used + assertSame(r1, primary.get(methodName).get()); + assertNull(secondary.get(methodName)); + assertNull(secondary.get(key)); + } + + public void testMultiConditionalCacheAndEvict(CacheableService<?> service) { + Cache primary = cm.getCache("primary"); + Cache secondary = cm.getCache("secondary"); + Object key = Integer.valueOf(1); + + secondary.put(key, key); + + assertNull(primary.get(key)); + assertSame(key, secondary.get(key).get()); + + Object r1 = service.multiConditionalCacheAndEvict(key); + Object r3 = service.multiConditionalCacheAndEvict(key); + + assertTrue(!r1.equals(r3)); + assertNull(primary.get(key)); + + Object key2 = Integer.valueOf(3); + Object r2 = service.multiConditionalCacheAndEvict(key2); + assertSame(r2, service.multiConditionalCacheAndEvict(key2)); + + // assert the method name is used + assertSame(r2, primary.get(key2).get()); + assertNull(secondary.get(key2)); + } + + @Test + public void testCacheable() throws Exception { + testCacheable(cs); + } + + @Test + public void testInvalidate() throws Exception { + testEvict(cs); + } + + @Test + public void testEarlyInvalidate() throws Exception { + testEvictEarly(cs); + } + + @Test + public void testEvictWithException() throws Exception { + testEvictException(cs); + } + + @Test + public void testEvictAll() throws Exception { + testEvictAll(cs); + } + + @Test + public void testInvalidateWithKey() throws Exception { + testEvictWKey(cs); + } + + @Test + public void testEarlyInvalidateWithKey() throws Exception { + testEvictWKeyEarly(cs); + } + + @Test + public void testConditionalExpression() throws Exception { + testConditionalExpression(cs); + } + + @Test + public void testKeyExpression() throws Exception { + testKeyExpression(cs); + } + + @Test + public void testClassCacheCacheable() throws Exception { + testCacheable(ccs); + } + + @Test + public void testClassCacheInvalidate() throws Exception { + testEvict(ccs); + } + + @Test + public void testClassEarlyInvalidate() throws Exception { + testEvictEarly(ccs); + } + + @Test + public void testClassEvictAll() throws Exception { + testEvictAll(ccs); + } + + @Test + public void testClassEvictWithException() throws Exception { + testEvictException(ccs); + } + + @Test + public void testClassCacheInvalidateWKey() throws Exception { + testEvictWKey(ccs); + } + + @Test + public void testClassEarlyInvalidateWithKey() throws Exception { + testEvictWKeyEarly(ccs); + } + + @Test + public void testNullValue() throws Exception { + testNullValue(cs); + } + + @Test + public void testClassNullValue() throws Exception { + Object key = new Object(); + assertNull(ccs.nullValue(key)); + int nr = ccs.nullInvocations().intValue(); + assertNull(ccs.nullValue(key)); + assertEquals(nr, ccs.nullInvocations().intValue()); + assertNull(ccs.nullValue(new Object())); + // the check method is also cached + assertEquals(nr, ccs.nullInvocations().intValue()); + assertEquals(nr + 1, AnnotatedClassCacheableService.nullInvocations.intValue()); + } + + @Test + public void testMethodName() throws Exception { + testMethodName(cs, "name"); + } + + @Test + public void testClassMethodName() throws Exception { + testMethodName(ccs, "namedefault"); + } + + @Test + public void testNullArg() throws Exception { + testNullArg(cs); + } + + @Test + public void testClassNullArg() throws Exception { + testNullArg(ccs); + } + + @Test + public void testCheckedException() throws Exception { + testCheckedThrowable(cs); + } + + @Test + public void testClassCheckedException() throws Exception { + testCheckedThrowable(ccs); + } + + @Test + public void testUncheckedException() throws Exception { + testUncheckedThrowable(cs); + } + + @Test + public void testClassUncheckedException() throws Exception { + testUncheckedThrowable(ccs); + } + + @Test + public void testUpdate() { + testCacheUpdate(cs); + } + + @Test + public void testClassUpdate() { + testCacheUpdate(ccs); + } + + @Test + public void testConditionalUpdate() { + testConditionalCacheUpdate(cs); + } + + @Test + public void testClassConditionalUpdate() { + testConditionalCacheUpdate(ccs); + } + + @Test + public void testMultiCache() { + testMultiCache(cs); + } + + @Test + public void testClassMultiCache() { + testMultiCache(ccs); + } + + @Test + public void testMultiEvict() { + testMultiEvict(cs); + } + + @Test + public void testClassMultiEvict() { + testMultiEvict(ccs); + } + + @Test + public void testMultiPut() { + testMultiPut(cs); + } + + @Test + public void testClassMultiPut() { + testMultiPut(ccs); + } + + @Test + public void testMultiCacheAndEvict() { + testMultiCacheAndEvict(cs); + } + + @Test + public void testClassMultiCacheAndEvict() { + testMultiCacheAndEvict(ccs); + } + + @Test + public void testMultiConditionalCacheAndEvict() { + testMultiConditionalCacheAndEvict(cs); + } + + @Test + public void testClassMultiConditionalCacheAndEvict() { + testMultiConditionalCacheAndEvict(ccs); + } } \ No newline at end of file diff --git a/org.springframework.aspects/src/test/java/org/springframework/cache/aspectj/AspectJAnnotationTest.java b/org.springframework.aspects/src/test/java/org/springframework/cache/aspectj/AspectJAnnotationTest.java index cd462583177..27c4e6d7d86 100644 --- a/org.springframework.aspects/src/test/java/org/springframework/cache/aspectj/AspectJAnnotationTest.java +++ b/org.springframework.aspects/src/test/java/org/springframework/cache/aspectj/AspectJAnnotationTest.java @@ -1,33 +1,33 @@ -/* - * Copyright 2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cache.aspectj; - -import org.springframework.context.ApplicationContext; -import org.springframework.context.support.GenericXmlApplicationContext; - - -/** - * @author Costin Leau - */ -public class AspectJAnnotationTest extends AbstractAnnotationTest { - - - @Override - protected ApplicationContext getApplicationContext() { - return new GenericXmlApplicationContext("/org/springframework/cache/config/annotation-cache-aspectj.xml"); - } -} +/* + * Copyright 2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cache.aspectj; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.GenericXmlApplicationContext; + + +/** + * @author Costin Leau + */ +public class AspectJAnnotationTest extends AbstractAnnotationTest { + + + @Override + protected ApplicationContext getApplicationContext() { + return new GenericXmlApplicationContext("/org/springframework/cache/config/annotation-cache-aspectj.xml"); + } +} diff --git a/org.springframework.aspects/src/test/java/org/springframework/cache/config/AnnotatedClassCacheableService.java b/org.springframework.aspects/src/test/java/org/springframework/cache/config/AnnotatedClassCacheableService.java index de138f5ecd7..a6d1b4f7bda 100644 --- a/org.springframework.aspects/src/test/java/org/springframework/cache/config/AnnotatedClassCacheableService.java +++ b/org.springframework.aspects/src/test/java/org/springframework/cache/config/AnnotatedClassCacheableService.java @@ -1,138 +1,138 @@ -/* - * Copyright 2010-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cache.config; - -import java.util.concurrent.atomic.AtomicLong; - -import org.springframework.cache.annotation.CacheEvict; -import org.springframework.cache.annotation.CachePut; -import org.springframework.cache.annotation.Cacheable; -import org.springframework.cache.annotation.Caching; - -/** - * @author Costin Leau - */ -@Cacheable("default") -public class AnnotatedClassCacheableService implements CacheableService<Object> { - - private final AtomicLong counter = new AtomicLong(); - public static final AtomicLong nullInvocations = new AtomicLong(); - - public Object cache(Object arg1) { - return counter.getAndIncrement(); - } - - public Object conditional(int field) { - return null; - } - - @CacheEvict("default") - public void invalidate(Object arg1) { - } - - @CacheEvict("default") - public void evictWithException(Object arg1) { - throw new RuntimeException("exception thrown - evict should NOT occur"); - } - - @CacheEvict(value = "default", allEntries = true) - public void evictAll(Object arg1) { - } - - @CacheEvict(value = "default", beforeInvocation = true) - public void evictEarly(Object arg1) { - throw new RuntimeException("exception thrown - evict should still occur"); - } - - @CacheEvict(value = "default", key = "#p0") - public void evict(Object arg1, Object arg2) { - } - - @CacheEvict(value = "default", key = "#p0", beforeInvocation = true) - public void invalidateEarly(Object arg1, Object arg2) { - throw new RuntimeException("exception thrown - evict should still occur"); - } - - @Cacheable(value = "default", key = "#p0") - public Object key(Object arg1, Object arg2) { - return counter.getAndIncrement(); - } - - @Cacheable(value = "default", key = "#root.methodName + #root.caches[0].name") - public Object name(Object arg1) { - return counter.getAndIncrement(); - } - - @Cacheable(value = "default", key = "#root.methodName + #root.method.name + #root.targetClass + #root.target") - public Object rootVars(Object arg1) { - return counter.getAndIncrement(); - } - - @CachePut("default") - public Object update(Object arg1) { - return counter.getAndIncrement(); - } - - @CachePut(value = "default", condition = "#arg.equals(3)") - public Object conditionalUpdate(Object arg) { - return arg; - } - - public Object nullValue(Object arg1) { - nullInvocations.incrementAndGet(); - return null; - } - - public Number nullInvocations() { - return nullInvocations.get(); - } - - public Long throwChecked(Object arg1) throws Exception { - throw new UnsupportedOperationException(arg1.toString()); - } - - public Long throwUnchecked(Object arg1) { - throw new UnsupportedOperationException(); - } - - // multi annotations - - @Caching(cacheable = { @Cacheable("primary"), @Cacheable("secondary") }) - public Object multiCache(Object arg1) { - return counter.getAndIncrement(); - } - - @Caching(evict = { @CacheEvict("primary"), @CacheEvict(value = "secondary", key = "#p0") }) - public Object multiEvict(Object arg1) { - return counter.getAndIncrement(); - } - - @Caching(cacheable = { @Cacheable(value = "primary", key = "#root.methodName") }, evict = { @CacheEvict("secondary") }) - public Object multiCacheAndEvict(Object arg1) { - return counter.getAndIncrement(); - } - - @Caching(cacheable = { @Cacheable(value = "primary", condition = "#p0 == 3") }, evict = { @CacheEvict("secondary") }) - public Object multiConditionalCacheAndEvict(Object arg1) { - return counter.getAndIncrement(); - } - - @Caching(put = { @CachePut("primary"), @CachePut("secondary") }) - public Object multiUpdate(Object arg1) { - return arg1; - } +/* + * Copyright 2010-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cache.config; + +import java.util.concurrent.atomic.AtomicLong; + +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.CachePut; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.cache.annotation.Caching; + +/** + * @author Costin Leau + */ +@Cacheable("default") +public class AnnotatedClassCacheableService implements CacheableService<Object> { + + private final AtomicLong counter = new AtomicLong(); + public static final AtomicLong nullInvocations = new AtomicLong(); + + public Object cache(Object arg1) { + return counter.getAndIncrement(); + } + + public Object conditional(int field) { + return null; + } + + @CacheEvict("default") + public void invalidate(Object arg1) { + } + + @CacheEvict("default") + public void evictWithException(Object arg1) { + throw new RuntimeException("exception thrown - evict should NOT occur"); + } + + @CacheEvict(value = "default", allEntries = true) + public void evictAll(Object arg1) { + } + + @CacheEvict(value = "default", beforeInvocation = true) + public void evictEarly(Object arg1) { + throw new RuntimeException("exception thrown - evict should still occur"); + } + + @CacheEvict(value = "default", key = "#p0") + public void evict(Object arg1, Object arg2) { + } + + @CacheEvict(value = "default", key = "#p0", beforeInvocation = true) + public void invalidateEarly(Object arg1, Object arg2) { + throw new RuntimeException("exception thrown - evict should still occur"); + } + + @Cacheable(value = "default", key = "#p0") + public Object key(Object arg1, Object arg2) { + return counter.getAndIncrement(); + } + + @Cacheable(value = "default", key = "#root.methodName + #root.caches[0].name") + public Object name(Object arg1) { + return counter.getAndIncrement(); + } + + @Cacheable(value = "default", key = "#root.methodName + #root.method.name + #root.targetClass + #root.target") + public Object rootVars(Object arg1) { + return counter.getAndIncrement(); + } + + @CachePut("default") + public Object update(Object arg1) { + return counter.getAndIncrement(); + } + + @CachePut(value = "default", condition = "#arg.equals(3)") + public Object conditionalUpdate(Object arg) { + return arg; + } + + public Object nullValue(Object arg1) { + nullInvocations.incrementAndGet(); + return null; + } + + public Number nullInvocations() { + return nullInvocations.get(); + } + + public Long throwChecked(Object arg1) throws Exception { + throw new UnsupportedOperationException(arg1.toString()); + } + + public Long throwUnchecked(Object arg1) { + throw new UnsupportedOperationException(); + } + + // multi annotations + + @Caching(cacheable = { @Cacheable("primary"), @Cacheable("secondary") }) + public Object multiCache(Object arg1) { + return counter.getAndIncrement(); + } + + @Caching(evict = { @CacheEvict("primary"), @CacheEvict(value = "secondary", key = "#p0") }) + public Object multiEvict(Object arg1) { + return counter.getAndIncrement(); + } + + @Caching(cacheable = { @Cacheable(value = "primary", key = "#root.methodName") }, evict = { @CacheEvict("secondary") }) + public Object multiCacheAndEvict(Object arg1) { + return counter.getAndIncrement(); + } + + @Caching(cacheable = { @Cacheable(value = "primary", condition = "#p0 == 3") }, evict = { @CacheEvict("secondary") }) + public Object multiConditionalCacheAndEvict(Object arg1) { + return counter.getAndIncrement(); + } + + @Caching(put = { @CachePut("primary"), @CachePut("secondary") }) + public Object multiUpdate(Object arg1) { + return arg1; + } } \ No newline at end of file diff --git a/org.springframework.aspects/src/test/java/org/springframework/cache/config/CacheableService.java b/org.springframework.aspects/src/test/java/org/springframework/cache/config/CacheableService.java index 6c3b61169df..cdcb73b2cbc 100644 --- a/org.springframework.aspects/src/test/java/org/springframework/cache/config/CacheableService.java +++ b/org.springframework.aspects/src/test/java/org/springframework/cache/config/CacheableService.java @@ -1,70 +1,70 @@ -/* - * Copyright 2010-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cache.config; - -/** - * Basic service interface. - * - * @author Costin Leau - */ -public interface CacheableService<T> { - - T cache(Object arg1); - - void invalidate(Object arg1); - - void evictEarly(Object arg1); - - void evictAll(Object arg1); - - void evictWithException(Object arg1); - - void evict(Object arg1, Object arg2); - - void invalidateEarly(Object arg1, Object arg2); - - T conditional(int field); - - T key(Object arg1, Object arg2); - - T name(Object arg1); - - T nullValue(Object arg1); - - T update(Object arg1); - - T conditionalUpdate(Object arg2); - - Number nullInvocations(); - - T rootVars(Object arg1); - - T throwChecked(Object arg1) throws Exception; - - T throwUnchecked(Object arg1); - - // multi annotations - T multiCache(Object arg1); - - T multiEvict(Object arg1); - - T multiCacheAndEvict(Object arg1); - - T multiConditionalCacheAndEvict(Object arg1); - - T multiUpdate(Object arg1); +/* + * Copyright 2010-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cache.config; + +/** + * Basic service interface. + * + * @author Costin Leau + */ +public interface CacheableService<T> { + + T cache(Object arg1); + + void invalidate(Object arg1); + + void evictEarly(Object arg1); + + void evictAll(Object arg1); + + void evictWithException(Object arg1); + + void evict(Object arg1, Object arg2); + + void invalidateEarly(Object arg1, Object arg2); + + T conditional(int field); + + T key(Object arg1, Object arg2); + + T name(Object arg1); + + T nullValue(Object arg1); + + T update(Object arg1); + + T conditionalUpdate(Object arg2); + + Number nullInvocations(); + + T rootVars(Object arg1); + + T throwChecked(Object arg1) throws Exception; + + T throwUnchecked(Object arg1); + + // multi annotations + T multiCache(Object arg1); + + T multiEvict(Object arg1); + + T multiCacheAndEvict(Object arg1); + + T multiConditionalCacheAndEvict(Object arg1); + + T multiUpdate(Object arg1); } \ No newline at end of file diff --git a/org.springframework.aspects/src/test/java/org/springframework/cache/config/DefaultCacheableService.java b/org.springframework.aspects/src/test/java/org/springframework/cache/config/DefaultCacheableService.java index 3565a8a0f4c..e8938a804e0 100644 --- a/org.springframework.aspects/src/test/java/org/springframework/cache/config/DefaultCacheableService.java +++ b/org.springframework.aspects/src/test/java/org/springframework/cache/config/DefaultCacheableService.java @@ -1,144 +1,144 @@ -/* - * Copyright 2010-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cache.config; - -import java.util.concurrent.atomic.AtomicLong; - -import org.springframework.cache.annotation.CacheEvict; -import org.springframework.cache.annotation.CachePut; -import org.springframework.cache.annotation.Cacheable; -import org.springframework.cache.annotation.Caching; - -/** - * Simple cacheable service - * - * @author Costin Leau - */ -public class DefaultCacheableService implements CacheableService<Long> { - - private final AtomicLong counter = new AtomicLong(); - private final AtomicLong nullInvocations = new AtomicLong(); - - @Cacheable("default") - public Long cache(Object arg1) { - return counter.getAndIncrement(); - } - - @CacheEvict("default") - public void invalidate(Object arg1) { - } - - @CacheEvict("default") - public void evictWithException(Object arg1) { - throw new RuntimeException("exception thrown - evict should NOT occur"); - } - - @CacheEvict(value = "default", allEntries = true) - public void evictAll(Object arg1) { - } - - @CacheEvict(value = "default", beforeInvocation = true) - public void evictEarly(Object arg1) { - throw new RuntimeException("exception thrown - evict should still occur"); - } - - @CacheEvict(value = "default", key = "#p0") - public void evict(Object arg1, Object arg2) { - } - - @CacheEvict(value = "default", key = "#p0", beforeInvocation = true) - public void invalidateEarly(Object arg1, Object arg2) { - throw new RuntimeException("exception thrown - evict should still occur"); - } - - @Cacheable(value = "default", condition = "#classField == 3") - public Long conditional(int classField) { - return counter.getAndIncrement(); - } - - @Cacheable(value = "default", key = "#p0") - public Long key(Object arg1, Object arg2) { - return counter.getAndIncrement(); - } - - @Cacheable(value = "default", key = "#root.methodName") - public Long name(Object arg1) { - return counter.getAndIncrement(); - } - - @Cacheable(value = "default", key = "#root.methodName + #root.method.name + #root.targetClass + #root.target") - public Long rootVars(Object arg1) { - return counter.getAndIncrement(); - } - - @CachePut("default") - public Long update(Object arg1) { - return counter.getAndIncrement(); - } - - @CachePut(value = "default", condition = "#arg.equals(3)") - public Long conditionalUpdate(Object arg) { - return Long.valueOf(arg.toString()); - } - - @Cacheable("default") - public Long nullValue(Object arg1) { - nullInvocations.incrementAndGet(); - return null; - } - - public Number nullInvocations() { - return nullInvocations.get(); - } - - @Cacheable("default") - public Long throwChecked(Object arg1) throws Exception { - throw new Exception(arg1.toString()); - } - - @Cacheable("default") - public Long throwUnchecked(Object arg1) { - throw new UnsupportedOperationException(arg1.toString()); - } - - // multi annotations - - @Caching(cacheable = { @Cacheable("primary"), @Cacheable("secondary") }) - public Long multiCache(Object arg1) { - return counter.getAndIncrement(); - } - - @Caching(evict = { @CacheEvict("primary"), @CacheEvict(value = "secondary", key = "#p0") }) - public Long multiEvict(Object arg1) { - return counter.getAndIncrement(); - } - - @Caching(cacheable = { @Cacheable(value = "primary", key = "#root.methodName") }, evict = { @CacheEvict("secondary") }) - public Long multiCacheAndEvict(Object arg1) { - return counter.getAndIncrement(); - } - - @Caching(cacheable = { @Cacheable(value = "primary", condition = "#p0 == 3") }, evict = { @CacheEvict("secondary") }) - public Long multiConditionalCacheAndEvict(Object arg1) { - return counter.getAndIncrement(); - } - - @Caching(put = { @CachePut("primary"), @CachePut("secondary") }) - public Long multiUpdate(Object arg1) { - return Long.valueOf(arg1.toString()); - } +/* + * Copyright 2010-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cache.config; + +import java.util.concurrent.atomic.AtomicLong; + +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.CachePut; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.cache.annotation.Caching; + +/** + * Simple cacheable service + * + * @author Costin Leau + */ +public class DefaultCacheableService implements CacheableService<Long> { + + private final AtomicLong counter = new AtomicLong(); + private final AtomicLong nullInvocations = new AtomicLong(); + + @Cacheable("default") + public Long cache(Object arg1) { + return counter.getAndIncrement(); + } + + @CacheEvict("default") + public void invalidate(Object arg1) { + } + + @CacheEvict("default") + public void evictWithException(Object arg1) { + throw new RuntimeException("exception thrown - evict should NOT occur"); + } + + @CacheEvict(value = "default", allEntries = true) + public void evictAll(Object arg1) { + } + + @CacheEvict(value = "default", beforeInvocation = true) + public void evictEarly(Object arg1) { + throw new RuntimeException("exception thrown - evict should still occur"); + } + + @CacheEvict(value = "default", key = "#p0") + public void evict(Object arg1, Object arg2) { + } + + @CacheEvict(value = "default", key = "#p0", beforeInvocation = true) + public void invalidateEarly(Object arg1, Object arg2) { + throw new RuntimeException("exception thrown - evict should still occur"); + } + + @Cacheable(value = "default", condition = "#classField == 3") + public Long conditional(int classField) { + return counter.getAndIncrement(); + } + + @Cacheable(value = "default", key = "#p0") + public Long key(Object arg1, Object arg2) { + return counter.getAndIncrement(); + } + + @Cacheable(value = "default", key = "#root.methodName") + public Long name(Object arg1) { + return counter.getAndIncrement(); + } + + @Cacheable(value = "default", key = "#root.methodName + #root.method.name + #root.targetClass + #root.target") + public Long rootVars(Object arg1) { + return counter.getAndIncrement(); + } + + @CachePut("default") + public Long update(Object arg1) { + return counter.getAndIncrement(); + } + + @CachePut(value = "default", condition = "#arg.equals(3)") + public Long conditionalUpdate(Object arg) { + return Long.valueOf(arg.toString()); + } + + @Cacheable("default") + public Long nullValue(Object arg1) { + nullInvocations.incrementAndGet(); + return null; + } + + public Number nullInvocations() { + return nullInvocations.get(); + } + + @Cacheable("default") + public Long throwChecked(Object arg1) throws Exception { + throw new Exception(arg1.toString()); + } + + @Cacheable("default") + public Long throwUnchecked(Object arg1) { + throw new UnsupportedOperationException(arg1.toString()); + } + + // multi annotations + + @Caching(cacheable = { @Cacheable("primary"), @Cacheable("secondary") }) + public Long multiCache(Object arg1) { + return counter.getAndIncrement(); + } + + @Caching(evict = { @CacheEvict("primary"), @CacheEvict(value = "secondary", key = "#p0") }) + public Long multiEvict(Object arg1) { + return counter.getAndIncrement(); + } + + @Caching(cacheable = { @Cacheable(value = "primary", key = "#root.methodName") }, evict = { @CacheEvict("secondary") }) + public Long multiCacheAndEvict(Object arg1) { + return counter.getAndIncrement(); + } + + @Caching(cacheable = { @Cacheable(value = "primary", condition = "#p0 == 3") }, evict = { @CacheEvict("secondary") }) + public Long multiConditionalCacheAndEvict(Object arg1) { + return counter.getAndIncrement(); + } + + @Caching(put = { @CachePut("primary"), @CachePut("secondary") }) + public Long multiUpdate(Object arg1) { + return Long.valueOf(arg1.toString()); + } } \ No newline at end of file diff --git a/org.springframework.aspects/src/test/java/org/springframework/mock/staticmock/AnnotationDrivenStaticEntityMockingControlTest.java b/org.springframework.aspects/src/test/java/org/springframework/mock/staticmock/AnnotationDrivenStaticEntityMockingControlTest.java index 97b08f5541e..e33e3aa3f3d 100644 --- a/org.springframework.aspects/src/test/java/org/springframework/mock/staticmock/AnnotationDrivenStaticEntityMockingControlTest.java +++ b/org.springframework.aspects/src/test/java/org/springframework/mock/staticmock/AnnotationDrivenStaticEntityMockingControlTest.java @@ -1,146 +1,146 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.mock.staticmock; - -import javax.persistence.PersistenceException; - -import junit.framework.Assert; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -import static org.springframework.mock.staticmock.AnnotationDrivenStaticEntityMockingControl.*; - - -/** - * Test for static entity mocking framework. - * @author Rod Johnson - * @author Ramnivas Laddad - * - */ -@MockStaticEntityMethods -@RunWith(JUnit4.class) -public class AnnotationDrivenStaticEntityMockingControlTest { - - @Test - public void testNoArgIntReturn() { - int expectedCount = 13; - Person.countPeople(); - expectReturn(expectedCount); - playback(); - Assert.assertEquals(expectedCount, Person.countPeople()); - } - - @Test(expected=PersistenceException.class) - public void testNoArgThrows() { - Person.countPeople(); - expectThrow(new PersistenceException()); - playback(); - Person.countPeople(); - } - - @Test - public void testArgMethodMatches() { - long id = 13; - Person found = new Person(); - Person.findPerson(id); - expectReturn(found); - playback(); - Assert.assertEquals(found, Person.findPerson(id)); - } - - - @Test - public void testLongSeriesOfCalls() { - long id1 = 13; - long id2 = 24; - Person found1 = new Person(); - Person.findPerson(id1); - expectReturn(found1); - Person found2 = new Person(); - Person.findPerson(id2); - expectReturn(found2); - Person.findPerson(id1); - expectReturn(found1); - Person.countPeople(); - expectReturn(0); - playback(); - - Assert.assertEquals(found1, Person.findPerson(id1)); - Assert.assertEquals(found2, Person.findPerson(id2)); - Assert.assertEquals(found1, Person.findPerson(id1)); - Assert.assertEquals(0, Person.countPeople()); - } - - // Note delegation is used when tests are invalid and should fail, as otherwise - // the failure will occur on the verify() method in the aspect after - // this method returns, failing the test case - @Test - public void testArgMethodNoMatchExpectReturn() { - try { - new Delegate().testArgMethodNoMatchExpectReturn(); - Assert.fail(); - } catch (IllegalArgumentException expected) { - } - } - - @Test(expected=IllegalArgumentException.class) - public void testArgMethodNoMatchExpectThrow() { - new Delegate().testArgMethodNoMatchExpectThrow(); - } - - private void called(Person found, long id) { - Assert.assertEquals(found, Person.findPerson(id)); - } - - @Test - public void testReentrant() { - long id = 13; - Person found = new Person(); - Person.findPerson(id); - expectReturn(found); - playback(); - called(found, id); - } - - @Test(expected=IllegalStateException.class) - public void testRejectUnexpectedCall() { - new Delegate().rejectUnexpectedCall(); - } - - @Test(expected=IllegalStateException.class) - public void testFailTooFewCalls() { - new Delegate().failTooFewCalls(); - } - - @Test - public void testEmpty() { - // Test that verification check doesn't blow up if no replay() call happened - } - - @Test(expected=IllegalStateException.class) - public void testDoesntEverReplay() { - new Delegate().doesntEverReplay(); - } - - @Test(expected=IllegalStateException.class) - public void testDoesntEverSetReturn() { - new Delegate().doesntEverSetReturn(); - } -} - +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.mock.staticmock; + +import javax.persistence.PersistenceException; + +import junit.framework.Assert; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +import static org.springframework.mock.staticmock.AnnotationDrivenStaticEntityMockingControl.*; + + +/** + * Test for static entity mocking framework. + * @author Rod Johnson + * @author Ramnivas Laddad + * + */ +@MockStaticEntityMethods +@RunWith(JUnit4.class) +public class AnnotationDrivenStaticEntityMockingControlTest { + + @Test + public void testNoArgIntReturn() { + int expectedCount = 13; + Person.countPeople(); + expectReturn(expectedCount); + playback(); + Assert.assertEquals(expectedCount, Person.countPeople()); + } + + @Test(expected=PersistenceException.class) + public void testNoArgThrows() { + Person.countPeople(); + expectThrow(new PersistenceException()); + playback(); + Person.countPeople(); + } + + @Test + public void testArgMethodMatches() { + long id = 13; + Person found = new Person(); + Person.findPerson(id); + expectReturn(found); + playback(); + Assert.assertEquals(found, Person.findPerson(id)); + } + + + @Test + public void testLongSeriesOfCalls() { + long id1 = 13; + long id2 = 24; + Person found1 = new Person(); + Person.findPerson(id1); + expectReturn(found1); + Person found2 = new Person(); + Person.findPerson(id2); + expectReturn(found2); + Person.findPerson(id1); + expectReturn(found1); + Person.countPeople(); + expectReturn(0); + playback(); + + Assert.assertEquals(found1, Person.findPerson(id1)); + Assert.assertEquals(found2, Person.findPerson(id2)); + Assert.assertEquals(found1, Person.findPerson(id1)); + Assert.assertEquals(0, Person.countPeople()); + } + + // Note delegation is used when tests are invalid and should fail, as otherwise + // the failure will occur on the verify() method in the aspect after + // this method returns, failing the test case + @Test + public void testArgMethodNoMatchExpectReturn() { + try { + new Delegate().testArgMethodNoMatchExpectReturn(); + Assert.fail(); + } catch (IllegalArgumentException expected) { + } + } + + @Test(expected=IllegalArgumentException.class) + public void testArgMethodNoMatchExpectThrow() { + new Delegate().testArgMethodNoMatchExpectThrow(); + } + + private void called(Person found, long id) { + Assert.assertEquals(found, Person.findPerson(id)); + } + + @Test + public void testReentrant() { + long id = 13; + Person found = new Person(); + Person.findPerson(id); + expectReturn(found); + playback(); + called(found, id); + } + + @Test(expected=IllegalStateException.class) + public void testRejectUnexpectedCall() { + new Delegate().rejectUnexpectedCall(); + } + + @Test(expected=IllegalStateException.class) + public void testFailTooFewCalls() { + new Delegate().failTooFewCalls(); + } + + @Test + public void testEmpty() { + // Test that verification check doesn't blow up if no replay() call happened + } + + @Test(expected=IllegalStateException.class) + public void testDoesntEverReplay() { + new Delegate().doesntEverReplay(); + } + + @Test(expected=IllegalStateException.class) + public void testDoesntEverSetReturn() { + new Delegate().doesntEverSetReturn(); + } +} + diff --git a/org.springframework.aspects/src/test/java/org/springframework/mock/staticmock/Delegate.java b/org.springframework.aspects/src/test/java/org/springframework/mock/staticmock/Delegate.java index 9c692c976b1..c99dfe0c2e3 100644 --- a/org.springframework.aspects/src/test/java/org/springframework/mock/staticmock/Delegate.java +++ b/org.springframework.aspects/src/test/java/org/springframework/mock/staticmock/Delegate.java @@ -1,92 +1,92 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.mock.staticmock; - -import java.rmi.RemoteException; - -import javax.persistence.PersistenceException; - -import junit.framework.Assert; - -import org.junit.Ignore; -import org.junit.Test; -import org.springframework.mock.staticmock.AnnotationDrivenStaticEntityMockingControl; -import org.springframework.mock.staticmock.MockStaticEntityMethods; - -//Used because verification failures occur after method returns, -//so we can't test for them in the test case itself -@MockStaticEntityMethods -@Ignore // This isn't meant for direct testing; rather it is driven from AnnotationDrivenStaticEntityMockingControl -public class Delegate { - - @Test - public void testArgMethodNoMatchExpectReturn() { - long id = 13; - Person found = new Person(); - Person.findPerson(id); - AnnotationDrivenStaticEntityMockingControl.expectReturn(found); - AnnotationDrivenStaticEntityMockingControl.playback(); - Assert.assertEquals(found, Person.findPerson(id + 1)); - } - - @Test - public void testArgMethodNoMatchExpectThrow() { - long id = 13; - Person found = new Person(); - Person.findPerson(id); - AnnotationDrivenStaticEntityMockingControl.expectThrow(new PersistenceException()); - AnnotationDrivenStaticEntityMockingControl.playback(); - Assert.assertEquals(found, Person.findPerson(id + 1)); - } - - @Test - public void failTooFewCalls() { - long id = 13; - Person found = new Person(); - Person.findPerson(id); - AnnotationDrivenStaticEntityMockingControl.expectReturn(found); - Person.countPeople(); - AnnotationDrivenStaticEntityMockingControl.expectReturn(25); - AnnotationDrivenStaticEntityMockingControl.playback(); - Assert.assertEquals(found, Person.findPerson(id)); - } - - @Test - public void doesntEverReplay() { - Person.countPeople(); - } - - @Test - public void doesntEverSetReturn() { - Person.countPeople(); - AnnotationDrivenStaticEntityMockingControl.playback(); - } - - @Test - public void rejectUnexpectedCall() { - AnnotationDrivenStaticEntityMockingControl.playback(); - Person.countPeople(); - } - - @Test(expected=RemoteException.class) - public void testVerificationFailsEvenWhenTestFailsInExpectedManner() throws RemoteException { - Person.countPeople(); - AnnotationDrivenStaticEntityMockingControl.playback(); - // No calls to allow verification failure - throw new RemoteException(); - } -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.mock.staticmock; + +import java.rmi.RemoteException; + +import javax.persistence.PersistenceException; + +import junit.framework.Assert; + +import org.junit.Ignore; +import org.junit.Test; +import org.springframework.mock.staticmock.AnnotationDrivenStaticEntityMockingControl; +import org.springframework.mock.staticmock.MockStaticEntityMethods; + +//Used because verification failures occur after method returns, +//so we can't test for them in the test case itself +@MockStaticEntityMethods +@Ignore // This isn't meant for direct testing; rather it is driven from AnnotationDrivenStaticEntityMockingControl +public class Delegate { + + @Test + public void testArgMethodNoMatchExpectReturn() { + long id = 13; + Person found = new Person(); + Person.findPerson(id); + AnnotationDrivenStaticEntityMockingControl.expectReturn(found); + AnnotationDrivenStaticEntityMockingControl.playback(); + Assert.assertEquals(found, Person.findPerson(id + 1)); + } + + @Test + public void testArgMethodNoMatchExpectThrow() { + long id = 13; + Person found = new Person(); + Person.findPerson(id); + AnnotationDrivenStaticEntityMockingControl.expectThrow(new PersistenceException()); + AnnotationDrivenStaticEntityMockingControl.playback(); + Assert.assertEquals(found, Person.findPerson(id + 1)); + } + + @Test + public void failTooFewCalls() { + long id = 13; + Person found = new Person(); + Person.findPerson(id); + AnnotationDrivenStaticEntityMockingControl.expectReturn(found); + Person.countPeople(); + AnnotationDrivenStaticEntityMockingControl.expectReturn(25); + AnnotationDrivenStaticEntityMockingControl.playback(); + Assert.assertEquals(found, Person.findPerson(id)); + } + + @Test + public void doesntEverReplay() { + Person.countPeople(); + } + + @Test + public void doesntEverSetReturn() { + Person.countPeople(); + AnnotationDrivenStaticEntityMockingControl.playback(); + } + + @Test + public void rejectUnexpectedCall() { + AnnotationDrivenStaticEntityMockingControl.playback(); + Person.countPeople(); + } + + @Test(expected=RemoteException.class) + public void testVerificationFailsEvenWhenTestFailsInExpectedManner() throws RemoteException { + Person.countPeople(); + AnnotationDrivenStaticEntityMockingControl.playback(); + // No calls to allow verification failure + throw new RemoteException(); + } +} diff --git a/org.springframework.aspects/src/test/java/org/springframework/mock/staticmock/Person.java b/org.springframework.aspects/src/test/java/org/springframework/mock/staticmock/Person.java index 8fb74167b6c..a3b15c59c63 100644 --- a/org.springframework.aspects/src/test/java/org/springframework/mock/staticmock/Person.java +++ b/org.springframework.aspects/src/test/java/org/springframework/mock/staticmock/Person.java @@ -1,24 +1,24 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.mock.staticmock; - -import javax.persistence.Entity; - -@Entity -public class Person { -} - +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.mock.staticmock; + +import javax.persistence.Entity; + +@Entity +public class Person { +} + diff --git a/org.springframework.aspects/src/test/java/org/springframework/mock/staticmock/Person_Roo_Entity.aj b/org.springframework.aspects/src/test/java/org/springframework/mock/staticmock/Person_Roo_Entity.aj index 799b2848bd2..4d30f14376d 100644 --- a/org.springframework.aspects/src/test/java/org/springframework/mock/staticmock/Person_Roo_Entity.aj +++ b/org.springframework.aspects/src/test/java/org/springframework/mock/staticmock/Person_Roo_Entity.aj @@ -1,100 +1,100 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.mock.staticmock; - -privileged aspect Person_Roo_Entity { - - @javax.persistence.PersistenceContext - transient javax.persistence.EntityManager Person.entityManager; - - @javax.persistence.Id - @javax.persistence.GeneratedValue(strategy = javax.persistence.GenerationType.AUTO) - @javax.persistence.Column(name = "id") - private java.lang.Long Person.id; - - @javax.persistence.Version - @javax.persistence.Column(name = "version") - private java.lang.Integer Person.version; - - public java.lang.Long Person.getId() { - return this.id; - } - - public void Person.setId(java.lang.Long id) { - this.id = id; - } - - public java.lang.Integer Person.getVersion() { - return this.version; - } - - public void Person.setVersion(java.lang.Integer version) { - this.version = version; - } - - @org.springframework.transaction.annotation.Transactional - public void Person.persist() { - if (this.entityManager == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)"); - this.entityManager.persist(this); - } - - @org.springframework.transaction.annotation.Transactional - public void Person.remove() { - if (this.entityManager == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)"); - this.entityManager.remove(this); - } - - @org.springframework.transaction.annotation.Transactional - public void Person.flush() { - if (this.entityManager == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)"); - this.entityManager.flush(); - } - - @org.springframework.transaction.annotation.Transactional - public void Person.merge() { - if (this.entityManager == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)"); - Person merged = this.entityManager.merge(this); - this.entityManager.flush(); - this.id = merged.getId(); - } - - public static long Person.countPeople() { - javax.persistence.EntityManager em = new Person().entityManager; - if (em == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)"); - return (Long) em.createQuery("select count(o) from Person o").getSingleResult(); - } - - public static java.util.List<Person> Person.findAllPeople() { - javax.persistence.EntityManager em = new Person().entityManager; - if (em == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)"); - return em.createQuery("select o from Person o").getResultList(); - } - - public static Person Person.findPerson(java.lang.Long id) { - if (id == null) throw new IllegalArgumentException("An identifier is required to retrieve an instance of Person"); - javax.persistence.EntityManager em = new Person().entityManager; - if (em == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)"); - return em.find(Person.class, id); - } - - public static java.util.List<Person> Person.findPersonEntries(int firstResult, int maxResults) { - javax.persistence.EntityManager em = new Person().entityManager; - if (em == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)"); - return em.createQuery("select o from Person o").setFirstResult(firstResult).setMaxResults(maxResults).getResultList(); - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.mock.staticmock; + +privileged aspect Person_Roo_Entity { + + @javax.persistence.PersistenceContext + transient javax.persistence.EntityManager Person.entityManager; + + @javax.persistence.Id + @javax.persistence.GeneratedValue(strategy = javax.persistence.GenerationType.AUTO) + @javax.persistence.Column(name = "id") + private java.lang.Long Person.id; + + @javax.persistence.Version + @javax.persistence.Column(name = "version") + private java.lang.Integer Person.version; + + public java.lang.Long Person.getId() { + return this.id; + } + + public void Person.setId(java.lang.Long id) { + this.id = id; + } + + public java.lang.Integer Person.getVersion() { + return this.version; + } + + public void Person.setVersion(java.lang.Integer version) { + this.version = version; + } + + @org.springframework.transaction.annotation.Transactional + public void Person.persist() { + if (this.entityManager == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)"); + this.entityManager.persist(this); + } + + @org.springframework.transaction.annotation.Transactional + public void Person.remove() { + if (this.entityManager == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)"); + this.entityManager.remove(this); + } + + @org.springframework.transaction.annotation.Transactional + public void Person.flush() { + if (this.entityManager == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)"); + this.entityManager.flush(); + } + + @org.springframework.transaction.annotation.Transactional + public void Person.merge() { + if (this.entityManager == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)"); + Person merged = this.entityManager.merge(this); + this.entityManager.flush(); + this.id = merged.getId(); + } + + public static long Person.countPeople() { + javax.persistence.EntityManager em = new Person().entityManager; + if (em == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)"); + return (Long) em.createQuery("select count(o) from Person o").getSingleResult(); + } + + public static java.util.List<Person> Person.findAllPeople() { + javax.persistence.EntityManager em = new Person().entityManager; + if (em == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)"); + return em.createQuery("select o from Person o").getResultList(); + } + + public static Person Person.findPerson(java.lang.Long id) { + if (id == null) throw new IllegalArgumentException("An identifier is required to retrieve an instance of Person"); + javax.persistence.EntityManager em = new Person().entityManager; + if (em == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)"); + return em.find(Person.class, id); + } + + public static java.util.List<Person> Person.findPersonEntries(int firstResult, int maxResults) { + javax.persistence.EntityManager em = new Person().entityManager; + if (em == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)"); + return em.createQuery("select o from Person o").setFirstResult(firstResult).setMaxResults(maxResults).getResultList(); + } + +} diff --git a/org.springframework.aspects/src/test/java/org/springframework/scheduling/aspectj/AnnotationAsyncExecutionAspectTests.java b/org.springframework.aspects/src/test/java/org/springframework/scheduling/aspectj/AnnotationAsyncExecutionAspectTests.java index f8d55a43d24..e2194cfe5ca 100644 --- a/org.springframework.aspects/src/test/java/org/springframework/scheduling/aspectj/AnnotationAsyncExecutionAspectTests.java +++ b/org.springframework.aspects/src/test/java/org/springframework/scheduling/aspectj/AnnotationAsyncExecutionAspectTests.java @@ -1,178 +1,178 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.scheduling.aspectj; - -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; - -import junit.framework.Assert; - -import static junit.framework.Assert.*; - -import org.junit.Before; -import org.junit.Test; -import org.springframework.core.task.SimpleAsyncTaskExecutor; -import org.springframework.scheduling.annotation.Async; -import org.springframework.scheduling.annotation.AsyncResult; - -/** - * @author Ramnivas Laddad - */ -public class AnnotationAsyncExecutionAspectTests { - - private static final long WAIT_TIME = 1000; //milli seconds - - private CountingExecutor executor; - - @Before - public void setUp() { - executor = new CountingExecutor(); - AnnotationAsyncExecutionAspect.aspectOf().setExecutor(executor); - } - - @Test - public void asyncMethodGetsRoutedAsynchronously() { - ClassWithoutAsyncAnnotation obj = new ClassWithoutAsyncAnnotation(); - obj.incrementAsync(); - executor.waitForCompletion(); - assertEquals(1, obj.counter); - assertEquals(1, executor.submitStartCounter); - assertEquals(1, executor.submitCompleteCounter); - } - - @Test - public void asyncMethodReturningFutureGetsRoutedAsynchronouslyAndReturnsAFuture() throws InterruptedException, ExecutionException { - ClassWithoutAsyncAnnotation obj = new ClassWithoutAsyncAnnotation(); - Future<Integer> future = obj.incrementReturningAFuture(); - // No need to executor.waitForCompletion() as future.get() will have the same effect - assertEquals(5, future.get().intValue()); - assertEquals(1, obj.counter); - assertEquals(1, executor.submitStartCounter); - assertEquals(1, executor.submitCompleteCounter); - } - - @Test - public void syncMethodGetsRoutedSynchronously() { - ClassWithoutAsyncAnnotation obj = new ClassWithoutAsyncAnnotation(); - obj.increment(); - assertEquals(1, obj.counter); - assertEquals(0, executor.submitStartCounter); - assertEquals(0, executor.submitCompleteCounter); - } - - @Test - public void voidMethodInAsyncClassGetsRoutedAsynchronously() { - ClassWithAsyncAnnotation obj = new ClassWithAsyncAnnotation(); - obj.increment(); - executor.waitForCompletion(); - assertEquals(1, obj.counter); - assertEquals(1, executor.submitStartCounter); - assertEquals(1, executor.submitCompleteCounter); - } - - @Test - public void methodReturningFutureInAsyncClassGetsRoutedAsynchronouslyAndReturnsAFuture() throws InterruptedException, ExecutionException { - ClassWithAsyncAnnotation obj = new ClassWithAsyncAnnotation(); - Future<Integer> future = obj.incrementReturningAFuture(); - assertEquals(5, future.get().intValue()); - assertEquals(1, obj.counter); - assertEquals(1, executor.submitStartCounter); - assertEquals(1, executor.submitCompleteCounter); - } - - @Test - public void methodReturningNonVoidNonFutureInAsyncClassGetsRoutedSynchronously() { - ClassWithAsyncAnnotation obj = new ClassWithAsyncAnnotation(); - int returnValue = obj.return5(); - assertEquals(5, returnValue); - assertEquals(0, executor.submitStartCounter); - assertEquals(0, executor.submitCompleteCounter); - } - - @SuppressWarnings("serial") - private static class CountingExecutor extends SimpleAsyncTaskExecutor { - int submitStartCounter; - int submitCompleteCounter; - - @Override - public <T> Future<T> submit(Callable<T> task) { - submitStartCounter++; - Future<T> future = super.submit(task); - submitCompleteCounter++; - synchronized (this) { - notifyAll(); - } - return future; - } - - public synchronized void waitForCompletion() { - try { - wait(WAIT_TIME); - } catch (InterruptedException e) { - Assert.fail("Didn't finish the async job in " + WAIT_TIME + " milliseconds"); - } - } - } - - static class ClassWithoutAsyncAnnotation { - int counter; - - @Async public void incrementAsync() { - counter++; - } - - public void increment() { - counter++; - } - - @Async public Future<Integer> incrementReturningAFuture() { - counter++; - return new AsyncResult<Integer>(5); - } - - // It should be an error to attach @Async to a method that returns a non-void - // or non-Future. - // We need to keep this commented out, otherwise there will be a compile-time error. - // Please uncomment and re-comment this periodically to check that the compiler - // produces an error message due to the 'declare error' statement - // in AnnotationAsyncExecutionAspect -// @Async public int getInt() { -// return 0; -// } - } - - @Async - static class ClassWithAsyncAnnotation { - int counter; - - public void increment() { - counter++; - } - - // Manually check that there is a warning from the 'declare warning' statement in AnnotationAsynchExecutionAspect - public int return5() { - return 5; - } - - public Future<Integer> incrementReturningAFuture() { - counter++; - return new AsyncResult<Integer>(5); - } - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.scheduling.aspectj; + +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +import junit.framework.Assert; + +import static junit.framework.Assert.*; + +import org.junit.Before; +import org.junit.Test; +import org.springframework.core.task.SimpleAsyncTaskExecutor; +import org.springframework.scheduling.annotation.Async; +import org.springframework.scheduling.annotation.AsyncResult; + +/** + * @author Ramnivas Laddad + */ +public class AnnotationAsyncExecutionAspectTests { + + private static final long WAIT_TIME = 1000; //milli seconds + + private CountingExecutor executor; + + @Before + public void setUp() { + executor = new CountingExecutor(); + AnnotationAsyncExecutionAspect.aspectOf().setExecutor(executor); + } + + @Test + public void asyncMethodGetsRoutedAsynchronously() { + ClassWithoutAsyncAnnotation obj = new ClassWithoutAsyncAnnotation(); + obj.incrementAsync(); + executor.waitForCompletion(); + assertEquals(1, obj.counter); + assertEquals(1, executor.submitStartCounter); + assertEquals(1, executor.submitCompleteCounter); + } + + @Test + public void asyncMethodReturningFutureGetsRoutedAsynchronouslyAndReturnsAFuture() throws InterruptedException, ExecutionException { + ClassWithoutAsyncAnnotation obj = new ClassWithoutAsyncAnnotation(); + Future<Integer> future = obj.incrementReturningAFuture(); + // No need to executor.waitForCompletion() as future.get() will have the same effect + assertEquals(5, future.get().intValue()); + assertEquals(1, obj.counter); + assertEquals(1, executor.submitStartCounter); + assertEquals(1, executor.submitCompleteCounter); + } + + @Test + public void syncMethodGetsRoutedSynchronously() { + ClassWithoutAsyncAnnotation obj = new ClassWithoutAsyncAnnotation(); + obj.increment(); + assertEquals(1, obj.counter); + assertEquals(0, executor.submitStartCounter); + assertEquals(0, executor.submitCompleteCounter); + } + + @Test + public void voidMethodInAsyncClassGetsRoutedAsynchronously() { + ClassWithAsyncAnnotation obj = new ClassWithAsyncAnnotation(); + obj.increment(); + executor.waitForCompletion(); + assertEquals(1, obj.counter); + assertEquals(1, executor.submitStartCounter); + assertEquals(1, executor.submitCompleteCounter); + } + + @Test + public void methodReturningFutureInAsyncClassGetsRoutedAsynchronouslyAndReturnsAFuture() throws InterruptedException, ExecutionException { + ClassWithAsyncAnnotation obj = new ClassWithAsyncAnnotation(); + Future<Integer> future = obj.incrementReturningAFuture(); + assertEquals(5, future.get().intValue()); + assertEquals(1, obj.counter); + assertEquals(1, executor.submitStartCounter); + assertEquals(1, executor.submitCompleteCounter); + } + + @Test + public void methodReturningNonVoidNonFutureInAsyncClassGetsRoutedSynchronously() { + ClassWithAsyncAnnotation obj = new ClassWithAsyncAnnotation(); + int returnValue = obj.return5(); + assertEquals(5, returnValue); + assertEquals(0, executor.submitStartCounter); + assertEquals(0, executor.submitCompleteCounter); + } + + @SuppressWarnings("serial") + private static class CountingExecutor extends SimpleAsyncTaskExecutor { + int submitStartCounter; + int submitCompleteCounter; + + @Override + public <T> Future<T> submit(Callable<T> task) { + submitStartCounter++; + Future<T> future = super.submit(task); + submitCompleteCounter++; + synchronized (this) { + notifyAll(); + } + return future; + } + + public synchronized void waitForCompletion() { + try { + wait(WAIT_TIME); + } catch (InterruptedException e) { + Assert.fail("Didn't finish the async job in " + WAIT_TIME + " milliseconds"); + } + } + } + + static class ClassWithoutAsyncAnnotation { + int counter; + + @Async public void incrementAsync() { + counter++; + } + + public void increment() { + counter++; + } + + @Async public Future<Integer> incrementReturningAFuture() { + counter++; + return new AsyncResult<Integer>(5); + } + + // It should be an error to attach @Async to a method that returns a non-void + // or non-Future. + // We need to keep this commented out, otherwise there will be a compile-time error. + // Please uncomment and re-comment this periodically to check that the compiler + // produces an error message due to the 'declare error' statement + // in AnnotationAsyncExecutionAspect +// @Async public int getInt() { +// return 0; +// } + } + + @Async + static class ClassWithAsyncAnnotation { + int counter; + + public void increment() { + counter++; + } + + // Manually check that there is a warning from the 'declare warning' statement in AnnotationAsynchExecutionAspect + public int return5() { + return 5; + } + + public Future<Integer> incrementReturningAFuture() { + counter++; + return new AsyncResult<Integer>(5); + } + } + +} diff --git a/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/ClassWithPrivateAnnotatedMember.java b/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/ClassWithPrivateAnnotatedMember.java index 899e0feb67b..6351d55d0d7 100644 --- a/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/ClassWithPrivateAnnotatedMember.java +++ b/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/ClassWithPrivateAnnotatedMember.java @@ -1,34 +1,34 @@ -/* - * Copyright 2002-2006 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Created on 11 Sep 2006 by Adrian Colyer - */ -package org.springframework.transaction.aspectj; - -import org.springframework.transaction.annotation.Transactional; - -/** - * @author Adrian Colyer - * @since 2.0 - */ -public class ClassWithPrivateAnnotatedMember { - - public void doSomething() { - doInTransaction(); - } - - @Transactional - private void doInTransaction() {} -} +/* + * Copyright 2002-2006 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Created on 11 Sep 2006 by Adrian Colyer + */ +package org.springframework.transaction.aspectj; + +import org.springframework.transaction.annotation.Transactional; + +/** + * @author Adrian Colyer + * @since 2.0 + */ +public class ClassWithPrivateAnnotatedMember { + + public void doSomething() { + doInTransaction(); + } + + @Transactional + private void doInTransaction() {} +} diff --git a/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/ClassWithProtectedAnnotatedMember.java b/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/ClassWithProtectedAnnotatedMember.java index a4cb30c50fe..f681c81e844 100644 --- a/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/ClassWithProtectedAnnotatedMember.java +++ b/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/ClassWithProtectedAnnotatedMember.java @@ -1,34 +1,34 @@ -/* - * Copyright 2002-2006 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Created on 11 Sep 2006 by Adrian Colyer - */ -package org.springframework.transaction.aspectj; - -import org.springframework.transaction.annotation.Transactional; - -/** - * @author Adrian Colyer - * @since 2.0 - */ -public class ClassWithProtectedAnnotatedMember { - - public void doSomething() { - doInTransaction(); - } - - @Transactional - protected void doInTransaction() {} -} +/* + * Copyright 2002-2006 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Created on 11 Sep 2006 by Adrian Colyer + */ +package org.springframework.transaction.aspectj; + +import org.springframework.transaction.annotation.Transactional; + +/** + * @author Adrian Colyer + * @since 2.0 + */ +public class ClassWithProtectedAnnotatedMember { + + public void doSomething() { + doInTransaction(); + } + + @Transactional + protected void doInTransaction() {} +} diff --git a/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/ITransactional.java b/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/ITransactional.java index 48670fbf6a4..19a115ea214 100644 --- a/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/ITransactional.java +++ b/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/ITransactional.java @@ -1,10 +1,10 @@ -package org.springframework.transaction.aspectj; - -import org.springframework.transaction.annotation.Transactional; - -@Transactional -public interface ITransactional { - - Object echo(Throwable t) throws Throwable; - -} +package org.springframework.transaction.aspectj; + +import org.springframework.transaction.annotation.Transactional; + +@Transactional +public interface ITransactional { + + Object echo(Throwable t) throws Throwable; + +} diff --git a/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/MethodAnnotationOnClassWithNoInterface.java b/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/MethodAnnotationOnClassWithNoInterface.java index 29b9b311b74..22cc31ebc65 100644 --- a/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/MethodAnnotationOnClassWithNoInterface.java +++ b/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/MethodAnnotationOnClassWithNoInterface.java @@ -1,19 +1,19 @@ -package org.springframework.transaction.aspectj; - -import org.springframework.transaction.annotation.Transactional; - -public class MethodAnnotationOnClassWithNoInterface { - - @Transactional(rollbackFor=InterruptedException.class) - public Object echo(Throwable t) throws Throwable { - if (t != null) { - throw t; - } - return t; - } - - public void noTransactionAttribute() { - - } - -} +package org.springframework.transaction.aspectj; + +import org.springframework.transaction.annotation.Transactional; + +public class MethodAnnotationOnClassWithNoInterface { + + @Transactional(rollbackFor=InterruptedException.class) + public Object echo(Throwable t) throws Throwable { + if (t != null) { + throw t; + } + return t; + } + + public void noTransactionAttribute() { + + } + +} diff --git a/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/TransactionAspectTests.java b/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/TransactionAspectTests.java index 39fedc70b3a..9449b2bcf70 100644 --- a/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/TransactionAspectTests.java +++ b/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/TransactionAspectTests.java @@ -1,261 +1,261 @@ -/* - * Copyright 2002-2007 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.transaction.aspectj; - -import java.lang.reflect.Method; - -import junit.framework.AssertionFailedError; - -import org.springframework.test.AbstractDependencyInjectionSpringContextTests; -import org.springframework.transaction.CallCountingTransactionManager; -import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource; -import org.springframework.transaction.interceptor.TransactionAspectSupport; -import org.springframework.transaction.interceptor.TransactionAttribute; - -/** - * @author Rod Johnson - * @author Ramnivas Laddad - */ -public class TransactionAspectTests extends AbstractDependencyInjectionSpringContextTests { - - private TransactionAspectSupport transactionAspect; - - private CallCountingTransactionManager txManager; - - private TransactionalAnnotationOnlyOnClassWithNoInterface annotationOnlyOnClassWithNoInterface; - - private ClassWithProtectedAnnotatedMember beanWithAnnotatedProtectedMethod; - - private ClassWithPrivateAnnotatedMember beanWithAnnotatedPrivateMethod; - - private MethodAnnotationOnClassWithNoInterface methodAnnotationOnly = new MethodAnnotationOnClassWithNoInterface(); - - - public void setAnnotationOnlyOnClassWithNoInterface( - TransactionalAnnotationOnlyOnClassWithNoInterface annotationOnlyOnClassWithNoInterface) { - this.annotationOnlyOnClassWithNoInterface = annotationOnlyOnClassWithNoInterface; - } - - public void setClassWithAnnotatedProtectedMethod(ClassWithProtectedAnnotatedMember aBean) { - this.beanWithAnnotatedProtectedMethod = aBean; - } - - public void setClassWithAnnotatedPrivateMethod(ClassWithPrivateAnnotatedMember aBean) { - this.beanWithAnnotatedPrivateMethod = aBean; - } - - public void setTransactionAspect(TransactionAspectSupport transactionAspect) { - this.transactionAspect = transactionAspect; - this.txManager = (CallCountingTransactionManager) transactionAspect.getTransactionManager(); - } - - public TransactionAspectSupport getTransactionAspect() { - return this.transactionAspect; - } - - @Override - protected String getConfigPath() { - return "TransactionAspectTests-context.xml"; - } - - - public void testCommitOnAnnotatedClass() throws Throwable { - txManager.clear(); - assertEquals(0, txManager.begun); - annotationOnlyOnClassWithNoInterface.echo(null); - assertEquals(1, txManager.commits); - } - - public void testCommitOnAnnotatedProtectedMethod() throws Throwable { - txManager.clear(); - assertEquals(0, txManager.begun); - beanWithAnnotatedProtectedMethod.doInTransaction(); - assertEquals(1, txManager.commits); - } - - public void testCommitOnAnnotatedPrivateMethod() throws Throwable { - txManager.clear(); - assertEquals(0, txManager.begun); - beanWithAnnotatedPrivateMethod.doSomething(); - assertEquals(1, txManager.commits); - } - - public void testNoCommitOnNonAnnotatedNonPublicMethodInTransactionalType() throws Throwable { - txManager.clear(); - assertEquals(0,txManager.begun); - annotationOnlyOnClassWithNoInterface.nonTransactionalMethod(); - assertEquals(0,txManager.begun); - } - - public void testCommitOnAnnotatedMethod() throws Throwable { - txManager.clear(); - assertEquals(0, txManager.begun); - methodAnnotationOnly.echo(null); - assertEquals(1, txManager.commits); - } - - - public static class NotTransactional { - public void noop() { - } - } - - public void testNotTransactional() throws Throwable { - txManager.clear(); - assertEquals(0, txManager.begun); - new NotTransactional().noop(); - assertEquals(0, txManager.begun); - } - - - public void testDefaultCommitOnAnnotatedClass() throws Throwable { - testRollback(new TransactionOperationCallback() { - public Object performTransactionalOperation() throws Throwable { - return annotationOnlyOnClassWithNoInterface.echo(new Exception()); - } - }, false); - } - - public void testDefaultRollbackOnAnnotatedClass() throws Throwable { - testRollback(new TransactionOperationCallback() { - public Object performTransactionalOperation() throws Throwable { - return annotationOnlyOnClassWithNoInterface.echo(new RuntimeException()); - } - }, true); - } - - - public static class SubclassOfClassWithTransactionalAnnotation extends TransactionalAnnotationOnlyOnClassWithNoInterface { - } - - public void testDefaultCommitOnSubclassOfAnnotatedClass() throws Throwable { - testRollback(new TransactionOperationCallback() { - public Object performTransactionalOperation() throws Throwable { - return new SubclassOfClassWithTransactionalAnnotation().echo(new Exception()); - } - }, false); - } - - public static class SubclassOfClassWithTransactionalMethodAnnotation extends MethodAnnotationOnClassWithNoInterface { - } - - public void testDefaultCommitOnSubclassOfClassWithTransactionalMethodAnnotated() throws Throwable { - testRollback(new TransactionOperationCallback() { - public Object performTransactionalOperation() throws Throwable { - return new SubclassOfClassWithTransactionalMethodAnnotation().echo(new Exception()); - } - }, false); - } - - public static class ImplementsAnnotatedInterface implements ITransactional { - public Object echo(Throwable t) throws Throwable { - if (t != null) { - throw t; - } - return t; - } - } - - public void testDefaultCommitOnImplementationOfAnnotatedInterface() throws Throwable { -// testRollback(new TransactionOperationCallback() { -// public Object performTransactionalOperation() throws Throwable { -// return new ImplementsAnnotatedInterface().echo(new Exception()); -// } -// }, false); - - final Exception ex = new Exception(); - testNotTransactional(new TransactionOperationCallback() { - public Object performTransactionalOperation() throws Throwable { - return new ImplementsAnnotatedInterface().echo(ex); - } - }, ex); - } - - /** - * Note: resolution does not occur. Thus we can't make a class transactional if - * it implements a transactionally annotated interface. This behaviour could only - * be changed in AbstractFallbackTransactionAttributeSource in Spring proper. - * @throws SecurityException - * @throws NoSuchMethodException - */ - public void testDoesNotResolveTxAnnotationOnMethodFromClassImplementingAnnotatedInterface() throws SecurityException, NoSuchMethodException { - AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource(); - Method m = ImplementsAnnotatedInterface.class.getMethod("echo", Throwable.class); - TransactionAttribute ta = atas.getTransactionAttribute(m, ImplementsAnnotatedInterface.class); - assertNull(ta); - } - - - public void testDefaultRollbackOnImplementationOfAnnotatedInterface() throws Throwable { -// testRollback(new TransactionOperationCallback() { -// public Object performTransactionalOperation() throws Throwable { -// return new ImplementsAnnotatedInterface().echo(new RuntimeException()); -// } -// }, true); - - final Exception rollbackProvokingException = new RuntimeException(); - testNotTransactional(new TransactionOperationCallback() { - public Object performTransactionalOperation() throws Throwable { - return new ImplementsAnnotatedInterface().echo(rollbackProvokingException); - } - }, rollbackProvokingException); - } - - - protected void testRollback(TransactionOperationCallback toc, boolean rollback) throws Throwable { - txManager.clear(); - assertEquals(0, txManager.begun); - try { - toc.performTransactionalOperation(); - assertEquals(1, txManager.commits); - } - catch (Throwable caught) { - if (caught instanceof AssertionFailedError) { - return; - } - } - - if (rollback) { - assertEquals(1, txManager.rollbacks); - } - assertEquals(1, txManager.begun); - } - - protected void testNotTransactional(TransactionOperationCallback toc, Throwable expected) throws Throwable { - txManager.clear(); - assertEquals(0, txManager.begun); - try { - toc.performTransactionalOperation(); - } - catch (Throwable t) { - if (expected == null) { - fail("Expected " + expected); - } - assertSame(expected, t); - } - finally { - assertEquals(0, txManager.begun); - } - } - - - private interface TransactionOperationCallback { - - Object performTransactionalOperation() throws Throwable; - } - -} +/* + * Copyright 2002-2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.transaction.aspectj; + +import java.lang.reflect.Method; + +import junit.framework.AssertionFailedError; + +import org.springframework.test.AbstractDependencyInjectionSpringContextTests; +import org.springframework.transaction.CallCountingTransactionManager; +import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource; +import org.springframework.transaction.interceptor.TransactionAspectSupport; +import org.springframework.transaction.interceptor.TransactionAttribute; + +/** + * @author Rod Johnson + * @author Ramnivas Laddad + */ +public class TransactionAspectTests extends AbstractDependencyInjectionSpringContextTests { + + private TransactionAspectSupport transactionAspect; + + private CallCountingTransactionManager txManager; + + private TransactionalAnnotationOnlyOnClassWithNoInterface annotationOnlyOnClassWithNoInterface; + + private ClassWithProtectedAnnotatedMember beanWithAnnotatedProtectedMethod; + + private ClassWithPrivateAnnotatedMember beanWithAnnotatedPrivateMethod; + + private MethodAnnotationOnClassWithNoInterface methodAnnotationOnly = new MethodAnnotationOnClassWithNoInterface(); + + + public void setAnnotationOnlyOnClassWithNoInterface( + TransactionalAnnotationOnlyOnClassWithNoInterface annotationOnlyOnClassWithNoInterface) { + this.annotationOnlyOnClassWithNoInterface = annotationOnlyOnClassWithNoInterface; + } + + public void setClassWithAnnotatedProtectedMethod(ClassWithProtectedAnnotatedMember aBean) { + this.beanWithAnnotatedProtectedMethod = aBean; + } + + public void setClassWithAnnotatedPrivateMethod(ClassWithPrivateAnnotatedMember aBean) { + this.beanWithAnnotatedPrivateMethod = aBean; + } + + public void setTransactionAspect(TransactionAspectSupport transactionAspect) { + this.transactionAspect = transactionAspect; + this.txManager = (CallCountingTransactionManager) transactionAspect.getTransactionManager(); + } + + public TransactionAspectSupport getTransactionAspect() { + return this.transactionAspect; + } + + @Override + protected String getConfigPath() { + return "TransactionAspectTests-context.xml"; + } + + + public void testCommitOnAnnotatedClass() throws Throwable { + txManager.clear(); + assertEquals(0, txManager.begun); + annotationOnlyOnClassWithNoInterface.echo(null); + assertEquals(1, txManager.commits); + } + + public void testCommitOnAnnotatedProtectedMethod() throws Throwable { + txManager.clear(); + assertEquals(0, txManager.begun); + beanWithAnnotatedProtectedMethod.doInTransaction(); + assertEquals(1, txManager.commits); + } + + public void testCommitOnAnnotatedPrivateMethod() throws Throwable { + txManager.clear(); + assertEquals(0, txManager.begun); + beanWithAnnotatedPrivateMethod.doSomething(); + assertEquals(1, txManager.commits); + } + + public void testNoCommitOnNonAnnotatedNonPublicMethodInTransactionalType() throws Throwable { + txManager.clear(); + assertEquals(0,txManager.begun); + annotationOnlyOnClassWithNoInterface.nonTransactionalMethod(); + assertEquals(0,txManager.begun); + } + + public void testCommitOnAnnotatedMethod() throws Throwable { + txManager.clear(); + assertEquals(0, txManager.begun); + methodAnnotationOnly.echo(null); + assertEquals(1, txManager.commits); + } + + + public static class NotTransactional { + public void noop() { + } + } + + public void testNotTransactional() throws Throwable { + txManager.clear(); + assertEquals(0, txManager.begun); + new NotTransactional().noop(); + assertEquals(0, txManager.begun); + } + + + public void testDefaultCommitOnAnnotatedClass() throws Throwable { + testRollback(new TransactionOperationCallback() { + public Object performTransactionalOperation() throws Throwable { + return annotationOnlyOnClassWithNoInterface.echo(new Exception()); + } + }, false); + } + + public void testDefaultRollbackOnAnnotatedClass() throws Throwable { + testRollback(new TransactionOperationCallback() { + public Object performTransactionalOperation() throws Throwable { + return annotationOnlyOnClassWithNoInterface.echo(new RuntimeException()); + } + }, true); + } + + + public static class SubclassOfClassWithTransactionalAnnotation extends TransactionalAnnotationOnlyOnClassWithNoInterface { + } + + public void testDefaultCommitOnSubclassOfAnnotatedClass() throws Throwable { + testRollback(new TransactionOperationCallback() { + public Object performTransactionalOperation() throws Throwable { + return new SubclassOfClassWithTransactionalAnnotation().echo(new Exception()); + } + }, false); + } + + public static class SubclassOfClassWithTransactionalMethodAnnotation extends MethodAnnotationOnClassWithNoInterface { + } + + public void testDefaultCommitOnSubclassOfClassWithTransactionalMethodAnnotated() throws Throwable { + testRollback(new TransactionOperationCallback() { + public Object performTransactionalOperation() throws Throwable { + return new SubclassOfClassWithTransactionalMethodAnnotation().echo(new Exception()); + } + }, false); + } + + public static class ImplementsAnnotatedInterface implements ITransactional { + public Object echo(Throwable t) throws Throwable { + if (t != null) { + throw t; + } + return t; + } + } + + public void testDefaultCommitOnImplementationOfAnnotatedInterface() throws Throwable { +// testRollback(new TransactionOperationCallback() { +// public Object performTransactionalOperation() throws Throwable { +// return new ImplementsAnnotatedInterface().echo(new Exception()); +// } +// }, false); + + final Exception ex = new Exception(); + testNotTransactional(new TransactionOperationCallback() { + public Object performTransactionalOperation() throws Throwable { + return new ImplementsAnnotatedInterface().echo(ex); + } + }, ex); + } + + /** + * Note: resolution does not occur. Thus we can't make a class transactional if + * it implements a transactionally annotated interface. This behaviour could only + * be changed in AbstractFallbackTransactionAttributeSource in Spring proper. + * @throws SecurityException + * @throws NoSuchMethodException + */ + public void testDoesNotResolveTxAnnotationOnMethodFromClassImplementingAnnotatedInterface() throws SecurityException, NoSuchMethodException { + AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource(); + Method m = ImplementsAnnotatedInterface.class.getMethod("echo", Throwable.class); + TransactionAttribute ta = atas.getTransactionAttribute(m, ImplementsAnnotatedInterface.class); + assertNull(ta); + } + + + public void testDefaultRollbackOnImplementationOfAnnotatedInterface() throws Throwable { +// testRollback(new TransactionOperationCallback() { +// public Object performTransactionalOperation() throws Throwable { +// return new ImplementsAnnotatedInterface().echo(new RuntimeException()); +// } +// }, true); + + final Exception rollbackProvokingException = new RuntimeException(); + testNotTransactional(new TransactionOperationCallback() { + public Object performTransactionalOperation() throws Throwable { + return new ImplementsAnnotatedInterface().echo(rollbackProvokingException); + } + }, rollbackProvokingException); + } + + + protected void testRollback(TransactionOperationCallback toc, boolean rollback) throws Throwable { + txManager.clear(); + assertEquals(0, txManager.begun); + try { + toc.performTransactionalOperation(); + assertEquals(1, txManager.commits); + } + catch (Throwable caught) { + if (caught instanceof AssertionFailedError) { + return; + } + } + + if (rollback) { + assertEquals(1, txManager.rollbacks); + } + assertEquals(1, txManager.begun); + } + + protected void testNotTransactional(TransactionOperationCallback toc, Throwable expected) throws Throwable { + txManager.clear(); + assertEquals(0, txManager.begun); + try { + toc.performTransactionalOperation(); + } + catch (Throwable t) { + if (expected == null) { + fail("Expected " + expected); + } + assertSame(expected, t); + } + finally { + assertEquals(0, txManager.begun); + } + } + + + private interface TransactionOperationCallback { + + Object performTransactionalOperation() throws Throwable; + } + +} diff --git a/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/TransactionalAnnotationOnlyOnClassWithNoInterface.java b/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/TransactionalAnnotationOnlyOnClassWithNoInterface.java index a111f572413..691506baa03 100644 --- a/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/TransactionalAnnotationOnlyOnClassWithNoInterface.java +++ b/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/TransactionalAnnotationOnlyOnClassWithNoInterface.java @@ -1,20 +1,20 @@ -package org.springframework.transaction.aspectj; - -import org.springframework.transaction.annotation.Transactional; - -@Transactional -public class TransactionalAnnotationOnlyOnClassWithNoInterface { - - public Object echo(Throwable t) throws Throwable { - if (t != null) { - throw t; - } - return t; - } - - void nonTransactionalMethod() { - // no-op - } - -} - +package org.springframework.transaction.aspectj; + +import org.springframework.transaction.annotation.Transactional; + +@Transactional +public class TransactionalAnnotationOnlyOnClassWithNoInterface { + + public Object echo(Throwable t) throws Throwable { + if (t != null) { + throw t; + } + return t; + } + + void nonTransactionalMethod() { + // no-op + } + +} + diff --git a/org.springframework.aspects/template.mf b/org.springframework.aspects/template.mf index a1cd0a1e916..27543caee4b 100644 --- a/org.springframework.aspects/template.mf +++ b/org.springframework.aspects/template.mf @@ -1,20 +1,20 @@ -Bundle-SymbolicName: org.springframework.aspects -Bundle-Name: Spring Aspects -Bundle-Vendor: SpringSource -Bundle-ManifestVersion: 2 -Import-Template: - javax.persistence;version="[1.0.0,3.0.0)";resolution:=optional, - org.apache.commons.logging.*;version="[1.1.1, 2.0.0)", - org.aspectj.*;version=${aj.osgi.range};resolution:=optional, - org.springframework.context.*;version=${spring.osgi.range}, - org.springframework.beans.*;version=${spring.osgi.range}, - org.springframework.cache.*;version=${spring.osgi.range};resolution:=optional, - org.springframework.core.*;version=${spring.osgi.range}, - org.springframework.dao.*;version=${spring.osgi.range};resolution:=optional, - org.springframework.orm.*;version=${spring.osgi.range};resolution:=optional, - org.springframework.scheduling.*;version=${spring.osgi.range};resolution:=optional, - org.springframework.transaction.*;version=${spring.osgi.range};resolution:=optional -Ignored-Existing-Headers: - Bnd-LastModified, - Import-Package, - Tool +Bundle-SymbolicName: org.springframework.aspects +Bundle-Name: Spring Aspects +Bundle-Vendor: SpringSource +Bundle-ManifestVersion: 2 +Import-Template: + javax.persistence;version="[1.0.0,3.0.0)";resolution:=optional, + org.apache.commons.logging.*;version="[1.1.1, 2.0.0)", + org.aspectj.*;version=${aj.osgi.range};resolution:=optional, + org.springframework.context.*;version=${spring.osgi.range}, + org.springframework.beans.*;version=${spring.osgi.range}, + org.springframework.cache.*;version=${spring.osgi.range};resolution:=optional, + org.springframework.core.*;version=${spring.osgi.range}, + org.springframework.dao.*;version=${spring.osgi.range};resolution:=optional, + org.springframework.orm.*;version=${spring.osgi.range};resolution:=optional, + org.springframework.scheduling.*;version=${spring.osgi.range};resolution:=optional, + org.springframework.transaction.*;version=${spring.osgi.range};resolution:=optional +Ignored-Existing-Headers: + Bnd-LastModified, + Import-Package, + Tool diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/annotation/Value.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/annotation/Value.java index b4e8d0399aa..2136666cfbd 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/annotation/Value.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/annotation/Value.java @@ -1,61 +1,61 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.beans.factory.annotation; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Annotation at the field or method/constructor parameter level - * that indicates a default value expression for the affected argument. - * - * <p>Typically used for expression-driven dependency injection. Also supported - * for dynamic resolution of handler method parameters, e.g. in Spring MVC. - * - * <p>A common use case is to assign default field values using - * "#{systemProperties.myProp}" style expressions. - * - * <p>Note that actual processing of the {@code @Value} annotation is performed - * by a {@link org.springframework.beans.factory.config.BeanPostProcessor - * BeanPostProcessor} which in turn means that you <em>cannot</em> use - * {@code @Value} within - * {@link org.springframework.beans.factory.config.BeanPostProcessor - * BeanPostProcessor} or {@link BeanFactoryPostProcessor} types. Please - * consult the javadoc for the {@link AutowiredAnnotationBeanPostProcessor} - * class (which, by default, checks for the presence of this annotation). - * - * @author Juergen Hoeller - * @since 3.0 - * @see AutowiredAnnotationBeanPostProcessor - * @see Autowired - * @see org.springframework.beans.factory.config.BeanExpressionResolver - * @see org.springframework.beans.factory.support.AutowireCandidateResolver#getSuggestedValue - */ -@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) -@Retention(RetentionPolicy.RUNTIME) -@Documented -public @interface Value { - - /** - * The actual value expression: e.g. "#{systemProperties.myProp}". - */ - String value(); - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.factory.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation at the field or method/constructor parameter level + * that indicates a default value expression for the affected argument. + * + * <p>Typically used for expression-driven dependency injection. Also supported + * for dynamic resolution of handler method parameters, e.g. in Spring MVC. + * + * <p>A common use case is to assign default field values using + * "#{systemProperties.myProp}" style expressions. + * + * <p>Note that actual processing of the {@code @Value} annotation is performed + * by a {@link org.springframework.beans.factory.config.BeanPostProcessor + * BeanPostProcessor} which in turn means that you <em>cannot</em> use + * {@code @Value} within + * {@link org.springframework.beans.factory.config.BeanPostProcessor + * BeanPostProcessor} or {@link BeanFactoryPostProcessor} types. Please + * consult the javadoc for the {@link AutowiredAnnotationBeanPostProcessor} + * class (which, by default, checks for the presence of this annotation). + * + * @author Juergen Hoeller + * @since 3.0 + * @see AutowiredAnnotationBeanPostProcessor + * @see Autowired + * @see org.springframework.beans.factory.config.BeanExpressionResolver + * @see org.springframework.beans.factory.support.AutowireCandidateResolver#getSuggestedValue + */ +@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface Value { + + /** + * The actual value expression: e.g. "#{systemProperties.myProp}". + */ + String value(); + +} diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/config/BeanExpressionContext.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/config/BeanExpressionContext.java index f74a6ad986f..1da52f0e203 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/config/BeanExpressionContext.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/config/BeanExpressionContext.java @@ -1,84 +1,84 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.beans.factory.config; - -import org.springframework.util.Assert; - -/** - * Context object for evaluating an expression within a bean definition. - * - * @author Juergen Hoeller - * @since 3.0 - */ -public class BeanExpressionContext { - - private final ConfigurableBeanFactory beanFactory; - - private final Scope scope; - - - public BeanExpressionContext(ConfigurableBeanFactory beanFactory, Scope scope) { - Assert.notNull(beanFactory, "BeanFactory must not be null"); - this.beanFactory = beanFactory; - this.scope = scope; - } - - public final ConfigurableBeanFactory getBeanFactory() { - return this.beanFactory; - } - - public final Scope getScope() { - return this.scope; - } - - - public boolean containsObject(String key) { - return (this.beanFactory.containsBean(key) || - (this.scope != null && this.scope.resolveContextualObject(key) != null)); - } - - public Object getObject(String key) { - if (this.beanFactory.containsBean(key)) { - return this.beanFactory.getBean(key); - } - else if (this.scope != null){ - return this.scope.resolveContextualObject(key); - } - else { - return null; - } - } - - - @Override - public boolean equals(Object other) { - if (this == other) { - return true; - } - if (!(other instanceof BeanExpressionContext)) { - return false; - } - BeanExpressionContext otherContext = (BeanExpressionContext) other; - return (this.beanFactory == otherContext.beanFactory && this.scope == otherContext.scope); - } - - @Override - public int hashCode() { - return this.beanFactory.hashCode(); - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.factory.config; + +import org.springframework.util.Assert; + +/** + * Context object for evaluating an expression within a bean definition. + * + * @author Juergen Hoeller + * @since 3.0 + */ +public class BeanExpressionContext { + + private final ConfigurableBeanFactory beanFactory; + + private final Scope scope; + + + public BeanExpressionContext(ConfigurableBeanFactory beanFactory, Scope scope) { + Assert.notNull(beanFactory, "BeanFactory must not be null"); + this.beanFactory = beanFactory; + this.scope = scope; + } + + public final ConfigurableBeanFactory getBeanFactory() { + return this.beanFactory; + } + + public final Scope getScope() { + return this.scope; + } + + + public boolean containsObject(String key) { + return (this.beanFactory.containsBean(key) || + (this.scope != null && this.scope.resolveContextualObject(key) != null)); + } + + public Object getObject(String key) { + if (this.beanFactory.containsBean(key)) { + return this.beanFactory.getBean(key); + } + else if (this.scope != null){ + return this.scope.resolveContextualObject(key); + } + else { + return null; + } + } + + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof BeanExpressionContext)) { + return false; + } + BeanExpressionContext otherContext = (BeanExpressionContext) other; + return (this.beanFactory == otherContext.beanFactory && this.scope == otherContext.scope); + } + + @Override + public int hashCode() { + return this.beanFactory.hashCode(); + } + +} diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/config/BeanExpressionResolver.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/config/BeanExpressionResolver.java index 589417d1a03..3b2604f15ac 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/config/BeanExpressionResolver.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/config/BeanExpressionResolver.java @@ -1,45 +1,45 @@ -/* - * Copyright 2002-2008 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.beans.factory.config; - -import org.springframework.beans.BeansException; - -/** - * Strategy interface for resolving a value through evaluating it - * as an expression, if applicable. - * - * <p>A raw {@link org.springframework.beans.factory.BeanFactory} does not - * contain a default implementation of this strategy. However, - * {@link org.springframework.context.ApplicationContext} implementations - * will provide expression support out of the box. - * - * @author Juergen Hoeller - * @since 3.0 - */ -public interface BeanExpressionResolver { - - /** - * Evaluate the given value as an expression, if applicable; - * return the value as-is otherwise. - * @param value the value to check - * @param evalContext the evaluation context - * @return the resolved value (potentially the given value as-is) - * @throws BeansException if evaluation failed - */ - Object evaluate(String value, BeanExpressionContext evalContext) throws BeansException; - -} +/* + * Copyright 2002-2008 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.factory.config; + +import org.springframework.beans.BeansException; + +/** + * Strategy interface for resolving a value through evaluating it + * as an expression, if applicable. + * + * <p>A raw {@link org.springframework.beans.factory.BeanFactory} does not + * contain a default implementation of this strategy. However, + * {@link org.springframework.context.ApplicationContext} implementations + * will provide expression support out of the box. + * + * @author Juergen Hoeller + * @since 3.0 + */ +public interface BeanExpressionResolver { + + /** + * Evaluate the given value as an expression, if applicable; + * return the value as-is otherwise. + * @param value the value to check + * @param evalContext the evaluation context + * @return the resolved value (potentially the given value as-is) + * @throws BeansException if evaluation failed + */ + Object evaluate(String value, BeanExpressionContext evalContext) throws BeansException; + +} diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/config/ProviderCreatingFactoryBean.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/config/ProviderCreatingFactoryBean.java index 657d4e7bb23..141ca3b17b0 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/config/ProviderCreatingFactoryBean.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/config/ProviderCreatingFactoryBean.java @@ -1,95 +1,95 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.beans.factory.config; - -import java.io.Serializable; -import javax.inject.Provider; - -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.util.Assert; - -/** - * A {@link org.springframework.beans.factory.FactoryBean} implementation that - * returns a value which is a JSR-330 {@link javax.inject.Provider} that in turn - * returns a bean sourced from a {@link org.springframework.beans.factory.BeanFactory}. - * - * <p>This is basically a JSR-330 compliant variant of Spring's good old - * {@link ObjectFactoryCreatingFactoryBean}. It can be used for traditional - * external dependency injection configuration that targets a property or - * constructor argument of type <code>javax.inject.Provider</code>, as an - * alternative to JSR-330's <code>@Inject</code> annotation-driven approach. - * - * @author Juergen Hoeller - * @since 3.0.2 - * @see javax.inject.Provider - * @see ObjectFactoryCreatingFactoryBean - */ -public class ProviderCreatingFactoryBean extends AbstractFactoryBean<Provider> { - - private String targetBeanName; - - - /** - * Set the name of the target bean. - * <p>The target does not <i>have</> to be a non-singleton bean, but realisticially - * always will be (because if the target bean were a singleton, then said singleton - * bean could simply be injected straight into the dependent object, thus obviating - * the need for the extra level of indirection afforded by this factory approach). - */ - public void setTargetBeanName(String targetBeanName) { - this.targetBeanName = targetBeanName; - } - - @Override - public void afterPropertiesSet() throws Exception { - Assert.hasText(this.targetBeanName, "Property 'targetBeanName' is required"); - super.afterPropertiesSet(); - } - - - @Override - public Class getObjectType() { - return Provider.class; - } - - @Override - protected Provider createInstance() { - return new TargetBeanProvider(getBeanFactory(), this.targetBeanName); - } - - - /** - * Independent inner class - for serialization purposes. - */ - private static class TargetBeanProvider implements Provider, Serializable { - - private final BeanFactory beanFactory; - - private final String targetBeanName; - - public TargetBeanProvider(BeanFactory beanFactory, String targetBeanName) { - this.beanFactory = beanFactory; - this.targetBeanName = targetBeanName; - } - - public Object get() throws BeansException { - return this.beanFactory.getBean(this.targetBeanName); - } - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.factory.config; + +import java.io.Serializable; +import javax.inject.Provider; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.util.Assert; + +/** + * A {@link org.springframework.beans.factory.FactoryBean} implementation that + * returns a value which is a JSR-330 {@link javax.inject.Provider} that in turn + * returns a bean sourced from a {@link org.springframework.beans.factory.BeanFactory}. + * + * <p>This is basically a JSR-330 compliant variant of Spring's good old + * {@link ObjectFactoryCreatingFactoryBean}. It can be used for traditional + * external dependency injection configuration that targets a property or + * constructor argument of type <code>javax.inject.Provider</code>, as an + * alternative to JSR-330's <code>@Inject</code> annotation-driven approach. + * + * @author Juergen Hoeller + * @since 3.0.2 + * @see javax.inject.Provider + * @see ObjectFactoryCreatingFactoryBean + */ +public class ProviderCreatingFactoryBean extends AbstractFactoryBean<Provider> { + + private String targetBeanName; + + + /** + * Set the name of the target bean. + * <p>The target does not <i>have</> to be a non-singleton bean, but realisticially + * always will be (because if the target bean were a singleton, then said singleton + * bean could simply be injected straight into the dependent object, thus obviating + * the need for the extra level of indirection afforded by this factory approach). + */ + public void setTargetBeanName(String targetBeanName) { + this.targetBeanName = targetBeanName; + } + + @Override + public void afterPropertiesSet() throws Exception { + Assert.hasText(this.targetBeanName, "Property 'targetBeanName' is required"); + super.afterPropertiesSet(); + } + + + @Override + public Class getObjectType() { + return Provider.class; + } + + @Override + protected Provider createInstance() { + return new TargetBeanProvider(getBeanFactory(), this.targetBeanName); + } + + + /** + * Independent inner class - for serialization purposes. + */ + private static class TargetBeanProvider implements Provider, Serializable { + + private final BeanFactory beanFactory; + + private final String targetBeanName; + + public TargetBeanProvider(BeanFactory beanFactory, String targetBeanName) { + this.beanFactory = beanFactory; + this.targetBeanName = targetBeanName; + } + + public Object get() throws BeansException { + return this.beanFactory.getBean(this.targetBeanName); + } + } + +} diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/ManagedArray.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/ManagedArray.java index 63492ea7f33..2be0e4152d8 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/ManagedArray.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/ManagedArray.java @@ -1,45 +1,45 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.beans.factory.support; - -import org.springframework.util.Assert; - -/** - * Tag collection class used to hold managed array elements, which may - * include runtime bean references (to be resolved into bean objects). - * - * @author Juergen Hoeller - * @since 3.0 - */ -public class ManagedArray extends ManagedList<Object> { - - /** Resolved element type for runtime creation of the target array */ - volatile Class resolvedElementType; - - - /** - * Create a new managed array placeholder. - * @param elementTypeName the target element type as a class name - * @param size the size of the array - */ - public ManagedArray(String elementTypeName, int size) { - super(size); - Assert.notNull(elementTypeName, "elementTypeName must not be null"); - setElementTypeName(elementTypeName); - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.factory.support; + +import org.springframework.util.Assert; + +/** + * Tag collection class used to hold managed array elements, which may + * include runtime bean references (to be resolved into bean objects). + * + * @author Juergen Hoeller + * @since 3.0 + */ +public class ManagedArray extends ManagedList<Object> { + + /** Resolved element type for runtime creation of the target array */ + volatile Class resolvedElementType; + + + /** + * Create a new managed array placeholder. + * @param elementTypeName the target element type as a class name + * @param size the size of the array + */ + public ManagedArray(String elementTypeName, int size) { + super(size); + Assert.notNull(elementTypeName, "elementTypeName must not be null"); + setElementTypeName(elementTypeName); + } + +} diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/SecurityContextProvider.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/SecurityContextProvider.java index ba09748b535..0403b8900f0 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/SecurityContextProvider.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/SecurityContextProvider.java @@ -1,35 +1,35 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.beans.factory.support; - -import java.security.AccessControlContext; - -/** - * Provider of the security context of the code running inside the bean factory. - * - * @author Costin Leau - * @since 3.0 - */ -public interface SecurityContextProvider { - - /** - * Provides a security access control context relevant to a bean factory. - * @return bean factory security control context - */ - AccessControlContext getAccessControlContext(); - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.factory.support; + +import java.security.AccessControlContext; + +/** + * Provider of the security context of the code running inside the bean factory. + * + * @author Costin Leau + * @since 3.0 + */ +public interface SecurityContextProvider { + + /** + * Provides a security access control context relevant to a bean factory. + * @return bean factory security control context + */ + AccessControlContext getAccessControlContext(); + +} diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/SimpleSecurityContextProvider.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/SimpleSecurityContextProvider.java index 14b9d883fe0..78b62938da5 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/SimpleSecurityContextProvider.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/SimpleSecurityContextProvider.java @@ -1,58 +1,58 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.beans.factory.support; - -import java.security.AccessControlContext; -import java.security.AccessController; - -/** - * Simple {@link SecurityContextProvider} implementation. - * - * @author Costin Leau - * @since 3.0 - */ -public class SimpleSecurityContextProvider implements SecurityContextProvider { - - private final AccessControlContext acc; - - - /** - * Construct a new <code>SimpleSecurityContextProvider</code> instance. - * <p>The security context will be retrieved on each call from the current - * thread. - */ - public SimpleSecurityContextProvider() { - this(null); - } - - /** - * Construct a new <code>SimpleSecurityContextProvider</code> instance. - * <p>If the given control context is null, the security context will be - * retrieved on each call from the current thread. - * @param acc access control context (can be <code>null</code>) - * @see AccessController#getContext() - */ - public SimpleSecurityContextProvider(AccessControlContext acc) { - this.acc = acc; - } - - - public AccessControlContext getAccessControlContext() { - return (this.acc != null ? acc : AccessController.getContext()); - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.factory.support; + +import java.security.AccessControlContext; +import java.security.AccessController; + +/** + * Simple {@link SecurityContextProvider} implementation. + * + * @author Costin Leau + * @since 3.0 + */ +public class SimpleSecurityContextProvider implements SecurityContextProvider { + + private final AccessControlContext acc; + + + /** + * Construct a new <code>SimpleSecurityContextProvider</code> instance. + * <p>The security context will be retrieved on each call from the current + * thread. + */ + public SimpleSecurityContextProvider() { + this(null); + } + + /** + * Construct a new <code>SimpleSecurityContextProvider</code> instance. + * <p>If the given control context is null, the security context will be + * retrieved on each call from the current thread. + * @param acc access control context (can be <code>null</code>) + * @see AccessController#getContext() + */ + public SimpleSecurityContextProvider(AccessControlContext acc) { + this.acc = acc; + } + + + public AccessControlContext getAccessControlContext() { + return (this.acc != null ? acc : AccessController.getContext()); + } + +} diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/SimpleConstructorNamespaceHandler.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/SimpleConstructorNamespaceHandler.java index 81d8632bf5a..a3656ec8bb9 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/SimpleConstructorNamespaceHandler.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/SimpleConstructorNamespaceHandler.java @@ -1,151 +1,151 @@ -/* - * Copyright 2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.beans.factory.xml; - -import java.util.Collection; - -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.config.BeanDefinitionHolder; -import org.springframework.beans.factory.config.ConstructorArgumentValues; -import org.springframework.beans.factory.config.RuntimeBeanReference; -import org.springframework.beans.factory.config.ConstructorArgumentValues.ValueHolder; -import org.springframework.core.Conventions; -import org.springframework.util.StringUtils; -import org.w3c.dom.Attr; -import org.w3c.dom.Element; -import org.w3c.dom.Node; - -/** - * Simple <code>NamespaceHandler</code> implementation that maps custom - * attributes directly through to bean properties. An important point to note is - * that this <code>NamespaceHandler</code> does not have a corresponding schema - * since there is no way to know in advance all possible attribute names. - * - * <p> - * An example of the usage of this <code>NamespaceHandler</code> is shown below: - * - * <pre class="code"> - * <bean id="author" class="..TestBean" c:name="Enescu" c:work-ref="compositions"/> - * </pre> - * - * Here the '<code>c:name</code>' corresponds directly to the '<code>name</code> - * ' argument declared on the constructor of class '<code>TestBean</code>'. The - * '<code>c:work-ref</code>' attributes corresponds to the '<code>work</code>' - * argument and, rather than being the concrete value, it contains the name of - * the bean that will be considered as a parameter. - * - * <b>Note</b>: This implementation supports only named parameters - there is no - * support for indexes or types. Further more, the names are used as hints by - * the container which, by default, does type introspection. - * - * @see SimplePropertyNamespaceHandler - * @author Costin Leau - */ -public class SimpleConstructorNamespaceHandler implements NamespaceHandler { - - private static final String REF_SUFFIX = "-ref"; - private static final String DELIMITER_PREFIX = "_"; - - public void init() { - } - - public BeanDefinition parse(Element element, ParserContext parserContext) { - parserContext.getReaderContext().error( - "Class [" + getClass().getName() + "] does not support custom elements.", element); - return null; - } - - public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definition, ParserContext parserContext) { - if (node instanceof Attr) { - Attr attr = (Attr) node; - String argName = StringUtils.trimWhitespace(parserContext.getDelegate().getLocalName(attr)); - String argValue = StringUtils.trimWhitespace(attr.getValue()); - - ConstructorArgumentValues cvs = definition.getBeanDefinition().getConstructorArgumentValues(); - boolean ref = false; - - // handle -ref arguments - if (argName.endsWith(REF_SUFFIX)) { - ref = true; - argName = argName.substring(0, argName.length() - REF_SUFFIX.length()); - } - - ValueHolder valueHolder = new ValueHolder(ref ? new RuntimeBeanReference(argValue) : argValue); - valueHolder.setSource(parserContext.getReaderContext().extractSource(attr)); - - // handle "escaped"/"_" arguments - if (argName.startsWith(DELIMITER_PREFIX)) { - String arg = argName.substring(1).trim(); - - // fast default check - if (!StringUtils.hasText(arg)) { - cvs.addGenericArgumentValue(valueHolder); - } - // assume an index otherwise - else { - int index = -1; - try { - index = Integer.parseInt(arg); - } catch (NumberFormatException ex) { - parserContext.getReaderContext().error( - "Constructor argument '" + argName + "' specifies an invalid integer", attr); - } - if (index < 0) { - parserContext.getReaderContext().error( - "Constructor argument '" + argName + "' specifies a negative index", attr); - } - - if (cvs.hasIndexedArgumentValue(index)){ - parserContext.getReaderContext().error( - "Constructor argument '" + argName + "' with index "+ index+" already defined using <constructor-arg>." + - " Only one approach may be used per argument.", attr); - } - - cvs.addIndexedArgumentValue(index, valueHolder); - } - } - // no escaping -> ctr name - else { - String name = Conventions.attributeNameToPropertyName(argName); - if (containsArgWithName(name, cvs)){ - parserContext.getReaderContext().error( - "Constructor argument '" + argName + "' already defined using <constructor-arg>." + - " Only one approach may be used per argument.", attr); - } - valueHolder.setName(Conventions.attributeNameToPropertyName(argName)); - cvs.addGenericArgumentValue(valueHolder); - } - } - return definition; - } - - private boolean containsArgWithName(String name, ConstructorArgumentValues cvs) { - if (!checkName(name, cvs.getGenericArgumentValues())) { - return checkName(name, cvs.getIndexedArgumentValues().values()); - } - - return true; - } - - private boolean checkName(String name, Collection<ValueHolder> values) { - for (ValueHolder holder : values) { - if (name.equals(holder.getName())) { - return true; - } - } - return false; - } +/* + * Copyright 2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.beans.factory.xml; + +import java.util.Collection; + +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.BeanDefinitionHolder; +import org.springframework.beans.factory.config.ConstructorArgumentValues; +import org.springframework.beans.factory.config.RuntimeBeanReference; +import org.springframework.beans.factory.config.ConstructorArgumentValues.ValueHolder; +import org.springframework.core.Conventions; +import org.springframework.util.StringUtils; +import org.w3c.dom.Attr; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +/** + * Simple <code>NamespaceHandler</code> implementation that maps custom + * attributes directly through to bean properties. An important point to note is + * that this <code>NamespaceHandler</code> does not have a corresponding schema + * since there is no way to know in advance all possible attribute names. + * + * <p> + * An example of the usage of this <code>NamespaceHandler</code> is shown below: + * + * <pre class="code"> + * <bean id="author" class="..TestBean" c:name="Enescu" c:work-ref="compositions"/> + * </pre> + * + * Here the '<code>c:name</code>' corresponds directly to the '<code>name</code> + * ' argument declared on the constructor of class '<code>TestBean</code>'. The + * '<code>c:work-ref</code>' attributes corresponds to the '<code>work</code>' + * argument and, rather than being the concrete value, it contains the name of + * the bean that will be considered as a parameter. + * + * <b>Note</b>: This implementation supports only named parameters - there is no + * support for indexes or types. Further more, the names are used as hints by + * the container which, by default, does type introspection. + * + * @see SimplePropertyNamespaceHandler + * @author Costin Leau + */ +public class SimpleConstructorNamespaceHandler implements NamespaceHandler { + + private static final String REF_SUFFIX = "-ref"; + private static final String DELIMITER_PREFIX = "_"; + + public void init() { + } + + public BeanDefinition parse(Element element, ParserContext parserContext) { + parserContext.getReaderContext().error( + "Class [" + getClass().getName() + "] does not support custom elements.", element); + return null; + } + + public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definition, ParserContext parserContext) { + if (node instanceof Attr) { + Attr attr = (Attr) node; + String argName = StringUtils.trimWhitespace(parserContext.getDelegate().getLocalName(attr)); + String argValue = StringUtils.trimWhitespace(attr.getValue()); + + ConstructorArgumentValues cvs = definition.getBeanDefinition().getConstructorArgumentValues(); + boolean ref = false; + + // handle -ref arguments + if (argName.endsWith(REF_SUFFIX)) { + ref = true; + argName = argName.substring(0, argName.length() - REF_SUFFIX.length()); + } + + ValueHolder valueHolder = new ValueHolder(ref ? new RuntimeBeanReference(argValue) : argValue); + valueHolder.setSource(parserContext.getReaderContext().extractSource(attr)); + + // handle "escaped"/"_" arguments + if (argName.startsWith(DELIMITER_PREFIX)) { + String arg = argName.substring(1).trim(); + + // fast default check + if (!StringUtils.hasText(arg)) { + cvs.addGenericArgumentValue(valueHolder); + } + // assume an index otherwise + else { + int index = -1; + try { + index = Integer.parseInt(arg); + } catch (NumberFormatException ex) { + parserContext.getReaderContext().error( + "Constructor argument '" + argName + "' specifies an invalid integer", attr); + } + if (index < 0) { + parserContext.getReaderContext().error( + "Constructor argument '" + argName + "' specifies a negative index", attr); + } + + if (cvs.hasIndexedArgumentValue(index)){ + parserContext.getReaderContext().error( + "Constructor argument '" + argName + "' with index "+ index+" already defined using <constructor-arg>." + + " Only one approach may be used per argument.", attr); + } + + cvs.addIndexedArgumentValue(index, valueHolder); + } + } + // no escaping -> ctr name + else { + String name = Conventions.attributeNameToPropertyName(argName); + if (containsArgWithName(name, cvs)){ + parserContext.getReaderContext().error( + "Constructor argument '" + argName + "' already defined using <constructor-arg>." + + " Only one approach may be used per argument.", attr); + } + valueHolder.setName(Conventions.attributeNameToPropertyName(argName)); + cvs.addGenericArgumentValue(valueHolder); + } + } + return definition; + } + + private boolean containsArgWithName(String name, ConstructorArgumentValues cvs) { + if (!checkName(name, cvs.getGenericArgumentValues())) { + return checkName(name, cvs.getIndexedArgumentValues().values()); + } + + return true; + } + + private boolean checkName(String name, Collection<ValueHolder> values) { + for (ValueHolder holder : values) { + if (name.equals(holder.getName())) { + return true; + } + } + return false; + } } \ No newline at end of file diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/propertyeditors/CurrencyEditor.java b/org.springframework.beans/src/main/java/org/springframework/beans/propertyeditors/CurrencyEditor.java index 004d8ed283e..910016ac863 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/propertyeditors/CurrencyEditor.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/propertyeditors/CurrencyEditor.java @@ -1,43 +1,43 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.beans.propertyeditors; - -import java.beans.PropertyEditorSupport; -import java.util.Currency; - -/** - * Editor for <code>java.util.Currency</code>, translating currency codes into Currency - * objects. Exposes the currency code as text representation of a Currency object. - * - * @author Juergen Hoeller - * @since 3.0 - * @see java.util.Currency - */ -public class CurrencyEditor extends PropertyEditorSupport { - - @Override - public void setAsText(String text) throws IllegalArgumentException { - setValue(Currency.getInstance(text)); - } - - @Override - public String getAsText() { - Currency value = (Currency) getValue(); - return (value != null ? value.getCurrencyCode() : ""); - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.propertyeditors; + +import java.beans.PropertyEditorSupport; +import java.util.Currency; + +/** + * Editor for <code>java.util.Currency</code>, translating currency codes into Currency + * objects. Exposes the currency code as text representation of a Currency object. + * + * @author Juergen Hoeller + * @since 3.0 + * @see java.util.Currency + */ +public class CurrencyEditor extends PropertyEditorSupport { + + @Override + public void setAsText(String text) throws IllegalArgumentException { + setValue(Currency.getInstance(text)); + } + + @Override + public String getAsText() { + Currency value = (Currency) getValue(); + return (value != null ? value.getCurrencyCode() : ""); + } + +} diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/propertyeditors/TimeZoneEditor.java b/org.springframework.beans/src/main/java/org/springframework/beans/propertyeditors/TimeZoneEditor.java index 323f4ca4c9d..832488ffaf0 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/propertyeditors/TimeZoneEditor.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/propertyeditors/TimeZoneEditor.java @@ -1,46 +1,46 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.beans.propertyeditors; - -import java.beans.PropertyEditorSupport; -import java.util.TimeZone; - -/** - * Editor for <code>java.util.TimeZone</code>, translating timezone IDs into - * TimeZone objects. Does not expose a text representation for TimeZone objects. - * - * @author Juergen Hoeller - * @since 3.0 - * @see java.util.TimeZone - */ -public class TimeZoneEditor extends PropertyEditorSupport { - - @Override - public void setAsText(String text) throws IllegalArgumentException { - setValue(TimeZone.getTimeZone(text)); - } - - /** - * This implementation returns <code>null</code> to indicate that - * there is no appropriate text representation. - */ - @Override - public String getAsText() { - return null; - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.propertyeditors; + +import java.beans.PropertyEditorSupport; +import java.util.TimeZone; + +/** + * Editor for <code>java.util.TimeZone</code>, translating timezone IDs into + * TimeZone objects. Does not expose a text representation for TimeZone objects. + * + * @author Juergen Hoeller + * @since 3.0 + * @see java.util.TimeZone + */ +public class TimeZoneEditor extends PropertyEditorSupport { + + @Override + public void setAsText(String text) throws IllegalArgumentException { + setValue(TimeZone.getTimeZone(text)); + } + + /** + * This implementation returns <code>null</code> to indicate that + * there is no appropriate text representation. + */ + @Override + public String getAsText() { + return null; + } + +} diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/propertyeditors/UUIDEditor.java b/org.springframework.beans/src/main/java/org/springframework/beans/propertyeditors/UUIDEditor.java index 885676962bb..98c9ea54f58 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/propertyeditors/UUIDEditor.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/propertyeditors/UUIDEditor.java @@ -1,50 +1,50 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.beans.propertyeditors; - -import java.beans.PropertyEditorSupport; -import java.util.UUID; - -import org.springframework.util.StringUtils; - -/** - * Editor for <code>java.util.UUID</code>, translating UUID - * String representations into UUID objects and back. - * - * @author Juergen Hoeller - * @since 3.0.1 - * @see java.util.UUID - */ -public class UUIDEditor extends PropertyEditorSupport { - - @Override - public void setAsText(String text) throws IllegalArgumentException { - if (StringUtils.hasText(text)) { - setValue(UUID.fromString(text)); - } - else { - setValue(null); - } - } - - @Override - public String getAsText() { - UUID value = (UUID) getValue(); - return (value != null ? value.toString() : ""); - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.propertyeditors; + +import java.beans.PropertyEditorSupport; +import java.util.UUID; + +import org.springframework.util.StringUtils; + +/** + * Editor for <code>java.util.UUID</code>, translating UUID + * String representations into UUID objects and back. + * + * @author Juergen Hoeller + * @since 3.0.1 + * @see java.util.UUID + */ +public class UUIDEditor extends PropertyEditorSupport { + + @Override + public void setAsText(String text) throws IllegalArgumentException { + if (StringUtils.hasText(text)) { + setValue(UUID.fromString(text)); + } + else { + setValue(null); + } + } + + @Override + public String getAsText() { + UUID value = (UUID) getValue(); + return (value != null ? value.toString() : ""); + } + +} diff --git a/org.springframework.beans/src/test/java/com/foo/Component.java b/org.springframework.beans/src/test/java/com/foo/Component.java index 20d7d7e3c7e..5c5d61ec81c 100644 --- a/org.springframework.beans/src/test/java/com/foo/Component.java +++ b/org.springframework.beans/src/test/java/com/foo/Component.java @@ -1,26 +1,26 @@ -package com.foo; - -import java.util.ArrayList; -import java.util.List; - -public class Component { - private String name; - private List<Component> components = new ArrayList<Component>(); - - // mmm, there is no setter method for the 'components' - public void addComponent(Component component) { - this.components.add(component); - } - - public List<Component> getComponents() { - return components; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } -} +package com.foo; + +import java.util.ArrayList; +import java.util.List; + +public class Component { + private String name; + private List<Component> components = new ArrayList<Component>(); + + // mmm, there is no setter method for the 'components' + public void addComponent(Component component) { + this.components.add(component); + } + + public List<Component> getComponents() { + return components; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/org.springframework.beans/src/test/java/com/foo/ComponentBeanDefinitionParser.java b/org.springframework.beans/src/test/java/com/foo/ComponentBeanDefinitionParser.java index 519d2a6bc53..3483077e854 100644 --- a/org.springframework.beans/src/test/java/com/foo/ComponentBeanDefinitionParser.java +++ b/org.springframework.beans/src/test/java/com/foo/ComponentBeanDefinitionParser.java @@ -1,52 +1,52 @@ -package com.foo; - -import java.util.List; - -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.support.AbstractBeanDefinition; -import org.springframework.beans.factory.support.BeanDefinitionBuilder; -import org.springframework.beans.factory.support.ManagedList; -import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser; -import org.springframework.beans.factory.xml.ParserContext; -import org.springframework.util.xml.DomUtils; -import org.w3c.dom.Element; - -public class ComponentBeanDefinitionParser extends AbstractBeanDefinitionParser { - - protected AbstractBeanDefinition parseInternal(Element element, - ParserContext parserContext) { - return parseComponentElement(element); - } - - private static AbstractBeanDefinition parseComponentElement(Element element) { - BeanDefinitionBuilder factory = BeanDefinitionBuilder - .rootBeanDefinition(ComponentFactoryBean.class); - - factory.addPropertyValue("parent", parseComponent(element)); - - List<Element> childElements = DomUtils.getChildElementsByTagName( - element, "component"); - if (childElements != null && childElements.size() > 0) { - parseChildComponents(childElements, factory); - } - - return factory.getBeanDefinition(); - } - - private static BeanDefinition parseComponent(Element element) { - BeanDefinitionBuilder component = BeanDefinitionBuilder - .rootBeanDefinition(Component.class); - component.addPropertyValue("name", element.getAttribute("name")); - return component.getBeanDefinition(); - } - - private static void parseChildComponents(List<Element> childElements, - BeanDefinitionBuilder factory) { - ManagedList<BeanDefinition> children = new ManagedList<BeanDefinition>( - childElements.size()); - for (Element element : childElements) { - children.add(parseComponentElement(element)); - } - factory.addPropertyValue("children", children); - } -} +package com.foo; + +import java.util.List; + +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.ManagedList; +import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.util.xml.DomUtils; +import org.w3c.dom.Element; + +public class ComponentBeanDefinitionParser extends AbstractBeanDefinitionParser { + + protected AbstractBeanDefinition parseInternal(Element element, + ParserContext parserContext) { + return parseComponentElement(element); + } + + private static AbstractBeanDefinition parseComponentElement(Element element) { + BeanDefinitionBuilder factory = BeanDefinitionBuilder + .rootBeanDefinition(ComponentFactoryBean.class); + + factory.addPropertyValue("parent", parseComponent(element)); + + List<Element> childElements = DomUtils.getChildElementsByTagName( + element, "component"); + if (childElements != null && childElements.size() > 0) { + parseChildComponents(childElements, factory); + } + + return factory.getBeanDefinition(); + } + + private static BeanDefinition parseComponent(Element element) { + BeanDefinitionBuilder component = BeanDefinitionBuilder + .rootBeanDefinition(Component.class); + component.addPropertyValue("name", element.getAttribute("name")); + return component.getBeanDefinition(); + } + + private static void parseChildComponents(List<Element> childElements, + BeanDefinitionBuilder factory) { + ManagedList<BeanDefinition> children = new ManagedList<BeanDefinition>( + childElements.size()); + for (Element element : childElements) { + children.add(parseComponentElement(element)); + } + factory.addPropertyValue("children", children); + } +} diff --git a/org.springframework.beans/src/test/java/com/foo/ComponentBeanDefinitionParserTest.java b/org.springframework.beans/src/test/java/com/foo/ComponentBeanDefinitionParserTest.java index 9b0cf6f5cb0..aec54454ece 100644 --- a/org.springframework.beans/src/test/java/com/foo/ComponentBeanDefinitionParserTest.java +++ b/org.springframework.beans/src/test/java/com/foo/ComponentBeanDefinitionParserTest.java @@ -1,74 +1,74 @@ -/* - * Copyright 2006-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.foo; - -import java.util.List; - -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; -import org.springframework.beans.factory.xml.XmlBeanFactory; -import org.springframework.core.io.ClassPathResource; - -import static org.junit.Assert.*; -import static org.hamcrest.CoreMatchers.*; - -/** - * @author Costin Leau - */ -public class ComponentBeanDefinitionParserTest { - - private static XmlBeanFactory bf; - - @BeforeClass - public static void setUpBeforeClass() throws Exception { - bf = new XmlBeanFactory(new ClassPathResource( - "com/foo/component-config.xml")); - } - - @AfterClass - public static void tearDownAfterClass() throws Exception { - bf.destroySingletons(); - } - - private Component getBionicFamily() { - return bf.getBean("bionic-family", Component.class); - } - - @Test - public void testBionicBasic() throws Exception { - Component cp = getBionicFamily(); - assertThat("Bionic-1", equalTo(cp.getName())); - } - - @Test - public void testBionicFirstLevelChildren() throws Exception { - Component cp = getBionicFamily(); - List<Component> components = cp.getComponents(); - assertThat(2, equalTo(components.size())); - assertThat("Mother-1", equalTo(components.get(0).getName())); - assertThat("Rock-1", equalTo(components.get(1).getName())); - } - - @Test - public void testBionicSecondLevenChildren() throws Exception { - Component cp = getBionicFamily(); - List<Component> components = cp.getComponents().get(0).getComponents(); - assertThat(2, equalTo(components.size())); - assertThat("Karate-1", equalTo(components.get(0).getName())); - assertThat("Sport-1", equalTo(components.get(1).getName())); - } +/* + * Copyright 2006-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.foo; + +import java.util.List; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.springframework.beans.factory.xml.XmlBeanFactory; +import org.springframework.core.io.ClassPathResource; + +import static org.junit.Assert.*; +import static org.hamcrest.CoreMatchers.*; + +/** + * @author Costin Leau + */ +public class ComponentBeanDefinitionParserTest { + + private static XmlBeanFactory bf; + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + bf = new XmlBeanFactory(new ClassPathResource( + "com/foo/component-config.xml")); + } + + @AfterClass + public static void tearDownAfterClass() throws Exception { + bf.destroySingletons(); + } + + private Component getBionicFamily() { + return bf.getBean("bionic-family", Component.class); + } + + @Test + public void testBionicBasic() throws Exception { + Component cp = getBionicFamily(); + assertThat("Bionic-1", equalTo(cp.getName())); + } + + @Test + public void testBionicFirstLevelChildren() throws Exception { + Component cp = getBionicFamily(); + List<Component> components = cp.getComponents(); + assertThat(2, equalTo(components.size())); + assertThat("Mother-1", equalTo(components.get(0).getName())); + assertThat("Rock-1", equalTo(components.get(1).getName())); + } + + @Test + public void testBionicSecondLevenChildren() throws Exception { + Component cp = getBionicFamily(); + List<Component> components = cp.getComponents().get(0).getComponents(); + assertThat(2, equalTo(components.size())); + assertThat("Karate-1", equalTo(components.get(0).getName())); + assertThat("Sport-1", equalTo(components.get(1).getName())); + } } \ No newline at end of file diff --git a/org.springframework.beans/src/test/java/com/foo/ComponentFactoryBean.java b/org.springframework.beans/src/test/java/com/foo/ComponentFactoryBean.java index dbc7a034728..e62eab786e1 100644 --- a/org.springframework.beans/src/test/java/com/foo/ComponentFactoryBean.java +++ b/org.springframework.beans/src/test/java/com/foo/ComponentFactoryBean.java @@ -1,35 +1,35 @@ -package com.foo; - -import java.util.List; - -import org.springframework.beans.factory.FactoryBean; - -public class ComponentFactoryBean implements FactoryBean<Component> { - private Component parent; - private List<Component> children; - - public void setParent(Component parent) { - this.parent = parent; - } - - public void setChildren(List<Component> children) { - this.children = children; - } - - public Component getObject() throws Exception { - if (this.children != null && this.children.size() > 0) { - for (Component child : children) { - this.parent.addComponent(child); - } - } - return this.parent; - } - - public Class<Component> getObjectType() { - return Component.class; - } - - public boolean isSingleton() { - return true; - } -} +package com.foo; + +import java.util.List; + +import org.springframework.beans.factory.FactoryBean; + +public class ComponentFactoryBean implements FactoryBean<Component> { + private Component parent; + private List<Component> children; + + public void setParent(Component parent) { + this.parent = parent; + } + + public void setChildren(List<Component> children) { + this.children = children; + } + + public Component getObject() throws Exception { + if (this.children != null && this.children.size() > 0) { + for (Component child : children) { + this.parent.addComponent(child); + } + } + return this.parent; + } + + public Class<Component> getObjectType() { + return Component.class; + } + + public boolean isSingleton() { + return true; + } +} diff --git a/org.springframework.beans/src/test/java/com/foo/ComponentNamespaceHandler.java b/org.springframework.beans/src/test/java/com/foo/ComponentNamespaceHandler.java index aff5ab6a8dd..3ccc7f167b5 100644 --- a/org.springframework.beans/src/test/java/com/foo/ComponentNamespaceHandler.java +++ b/org.springframework.beans/src/test/java/com/foo/ComponentNamespaceHandler.java @@ -1,10 +1,10 @@ -package com.foo; - -import org.springframework.beans.factory.xml.NamespaceHandlerSupport; - -public class ComponentNamespaceHandler extends NamespaceHandlerSupport { - public void init() { - registerBeanDefinitionParser("component", - new ComponentBeanDefinitionParser()); - } -} +package com.foo; + +import org.springframework.beans.factory.xml.NamespaceHandlerSupport; + +public class ComponentNamespaceHandler extends NamespaceHandlerSupport { + public void init() { + registerBeanDefinitionParser("component", + new ComponentBeanDefinitionParser()); + } +} diff --git a/org.springframework.beans/src/test/java/org/springframework/beans/factory/support/security/CallbacksSecurityTests.java b/org.springframework.beans/src/test/java/org/springframework/beans/factory/support/security/CallbacksSecurityTests.java index e48bcc5bec6..d0bec204919 100644 --- a/org.springframework.beans/src/test/java/org/springframework/beans/factory/support/security/CallbacksSecurityTests.java +++ b/org.springframework.beans/src/test/java/org/springframework/beans/factory/support/security/CallbacksSecurityTests.java @@ -1,525 +1,525 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.beans.factory.support.security; - -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertNotNull; -import static junit.framework.Assert.assertNull; -import static junit.framework.Assert.assertTrue; -import static junit.framework.Assert.fail; - -import java.lang.reflect.Method; -import java.net.URL; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.Permissions; -import java.security.Policy; -import java.security.Principal; -import java.security.PrivilegedAction; -import java.security.PrivilegedExceptionAction; -import java.security.ProtectionDomain; -import java.util.PropertyPermission; -import java.util.Set; - -import javax.security.auth.AuthPermission; -import javax.security.auth.Subject; - -import org.junit.Before; -import org.junit.Test; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanClassLoaderAware; -import org.springframework.beans.factory.BeanCreationException; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; -import org.springframework.beans.factory.BeanNameAware; -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.SmartFactoryBean; -import org.springframework.beans.factory.config.ConfigurableBeanFactory; -import org.springframework.beans.factory.support.BeanDefinitionBuilder; -import org.springframework.beans.factory.support.DefaultListableBeanFactory; -import org.springframework.beans.factory.support.SecurityContextProvider; -import org.springframework.beans.factory.support.security.support.ConstructorBean; -import org.springframework.beans.factory.support.security.support.CustomCallbackBean; -import org.springframework.beans.factory.xml.XmlBeanFactory; -import org.springframework.core.io.DefaultResourceLoader; -import org.springframework.core.io.Resource; - -/** - * Security test case. Checks whether the container uses its privileges for its - * internal work but does not leak them when touching/calling user code. - * - *t The first half of the test case checks that permissions are downgraded when - * calling user code while the second half that the caller code permission get - * through and Spring doesn't override the permission stack. - * - * @author Costin Leau - */ -public class CallbacksSecurityTests { - - private XmlBeanFactory beanFactory; - private SecurityContextProvider provider; - - private static class NonPrivilegedBean { - - private String expectedName; - public static boolean destroyed = false; - - public NonPrivilegedBean(String expected) { - this.expectedName = expected; - checkCurrentContext(); - } - - public void init() { - checkCurrentContext(); - } - - public void destroy() { - checkCurrentContext(); - destroyed = true; - } - - public void setProperty(Object value) { - checkCurrentContext(); - } - - public Object getProperty() { - checkCurrentContext(); - return null; - } - - public void setListProperty(Object value) { - checkCurrentContext(); - } - - public Object getListProperty() { - checkCurrentContext(); - return null; - } - - private void checkCurrentContext() { - assertEquals(expectedName, getCurrentSubjectName()); - } - } - - private static class NonPrivilegedSpringCallbacksBean implements - InitializingBean, DisposableBean, BeanClassLoaderAware, - BeanFactoryAware, BeanNameAware { - - private String expectedName; - public static boolean destroyed = false; - - public NonPrivilegedSpringCallbacksBean(String expected) { - this.expectedName = expected; - checkCurrentContext(); - } - - public void afterPropertiesSet() { - checkCurrentContext(); - } - - public void destroy() { - checkCurrentContext(); - destroyed = true; - } - - public void setBeanName(String name) { - checkCurrentContext(); - } - - public void setBeanClassLoader(ClassLoader classLoader) { - checkCurrentContext(); - } - - public void setBeanFactory(BeanFactory beanFactory) - throws BeansException { - checkCurrentContext(); - } - - private void checkCurrentContext() { - assertEquals(expectedName, getCurrentSubjectName()); - } - } - - private static class NonPrivilegedFactoryBean implements SmartFactoryBean { - private String expectedName; - - public NonPrivilegedFactoryBean(String expected) { - this.expectedName = expected; - checkCurrentContext(); - } - - public boolean isEagerInit() { - checkCurrentContext(); - return false; - } - - public boolean isPrototype() { - checkCurrentContext(); - return true; - } - - public Object getObject() throws Exception { - checkCurrentContext(); - return new Object(); - } - - public Class getObjectType() { - checkCurrentContext(); - return Object.class; - } - - public boolean isSingleton() { - checkCurrentContext(); - return false; - } - - private void checkCurrentContext() { - assertEquals(expectedName, getCurrentSubjectName()); - } - } - - private static class NonPrivilegedFactory { - - private final String expectedName; - - public NonPrivilegedFactory(String expected) { - this.expectedName = expected; - assertEquals(expectedName, getCurrentSubjectName()); - } - - public static Object makeStaticInstance(String expectedName) { - assertEquals(expectedName, getCurrentSubjectName()); - return new Object(); - } - - public Object makeInstance() { - assertEquals(expectedName, getCurrentSubjectName()); - return new Object(); - } - } - - private static String getCurrentSubjectName() { - final AccessControlContext acc = AccessController.getContext(); - - return AccessController.doPrivileged(new PrivilegedAction<String>() { - - public String run() { - Subject subject = Subject.getSubject(acc); - if (subject == null) { - return null; - } - - Set<Principal> principals = subject.getPrincipals(); - - if (principals == null) { - return null; - } - for (Principal p : principals) { - return p.getName(); - } - return null; - } - }); - } - - private static class TestPrincipal implements Principal { - - private String name; - - public TestPrincipal(String name) { - this.name = name; - } - - public String getName() { - return this.name; - } - - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - if (!(obj instanceof TestPrincipal)) { - return false; - } - TestPrincipal p = (TestPrincipal) obj; - return this.name.equals(p.name); - } - - public int hashCode() { - return this.name.hashCode(); - } - } - - public CallbacksSecurityTests() { - // setup security - if (System.getSecurityManager() == null) { - Policy policy = Policy.getPolicy(); - URL policyURL = getClass() - .getResource( - "/org/springframework/beans/factory/support/security/policy.all"); - System.setProperty("java.security.policy", policyURL.toString()); - System.setProperty("policy.allowSystemProperty", "true"); - policy.refresh(); - - System.setSecurityManager(new SecurityManager()); - } - } - - @Before - public void setUp() throws Exception { - - final ProtectionDomain empty = new ProtectionDomain(null, - new Permissions()); - - provider = new SecurityContextProvider() { - private final AccessControlContext acc = new AccessControlContext( - new ProtectionDomain[] { empty }); - - public AccessControlContext getAccessControlContext() { - return acc; - } - }; - - DefaultResourceLoader drl = new DefaultResourceLoader(); - Resource config = drl - .getResource("/org/springframework/beans/factory/support/security/callbacks.xml"); - beanFactory = new XmlBeanFactory(config); - beanFactory.setSecurityContextProvider(provider); - } - - @Test - public void testSecuritySanity() throws Exception { - AccessControlContext acc = provider.getAccessControlContext(); - try { - acc.checkPermission(new PropertyPermission("*", "read")); - fail("Acc should not have any permissions"); - } catch (SecurityException se) { - // expected - } - - final CustomCallbackBean bean = new CustomCallbackBean(); - final Method method = bean.getClass().getMethod("destroy", null); - method.setAccessible(true); - - try { - AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { - - public Object run() throws Exception { - method.invoke(bean, null); - return null; - } - }, acc); - fail("expected security exception"); - } catch (Exception ex) { - } - - final Class<ConstructorBean> cl = ConstructorBean.class; - try { - AccessController.doPrivileged( - new PrivilegedExceptionAction<Object>() { - - public Object run() throws Exception { - return cl.newInstance(); - } - }, acc); - fail("expected security exception"); - } catch (Exception ex) { - } - } - - @Test - public void testSpringInitBean() throws Exception { - try { - beanFactory.getBean("spring-init"); - fail("expected security exception"); - } catch (BeanCreationException ex) { - assertTrue(ex.getCause() instanceof SecurityException); - } - } - - @Test - public void testCustomInitBean() throws Exception { - try { - beanFactory.getBean("custom-init"); - fail("expected security exception"); - } catch (BeanCreationException ex) { - assertTrue(ex.getCause() instanceof SecurityException); - } - } - - @Test - public void testSpringDestroyBean() throws Exception { - beanFactory.getBean("spring-destroy"); - beanFactory.destroySingletons(); - assertNull(System.getProperty("security.destroy")); - } - - @Test - public void testCustomDestroyBean() throws Exception { - beanFactory.getBean("custom-destroy"); - beanFactory.destroySingletons(); - assertNull(System.getProperty("security.destroy")); - } - - @Test - public void testCustomFactoryObject() throws Exception { - try { - beanFactory.getBean("spring-factory"); - fail("expected security exception"); - } catch (BeanCreationException ex) { - assertTrue(ex.getCause() instanceof SecurityException); - } - - } - - @Test - public void testCustomFactoryType() throws Exception { - assertNull(beanFactory.getType("spring-factory")); - assertNull(System.getProperty("factory.object.type")); - } - - @Test - public void testCustomStaticFactoryMethod() throws Exception { - try { - beanFactory.getBean("custom-static-factory-method"); - fail("expected security exception"); - } catch (BeanCreationException ex) { - assertTrue(ex.getMostSpecificCause() instanceof SecurityException); - } - } - - @Test - public void testCustomInstanceFactoryMethod() throws Exception { - try { - beanFactory.getBean("custom-factory-method"); - fail("expected security exception"); - } catch (BeanCreationException ex) { - assertTrue(ex.getMostSpecificCause() instanceof SecurityException); - } - } - - @Test - public void testTrustedFactoryMethod() throws Exception { - try { - beanFactory.getBean("privileged-static-factory-method"); - fail("expected security exception"); - } catch (BeanCreationException ex) { - assertTrue(ex.getMostSpecificCause() instanceof SecurityException); - } - } - - @Test - public void testConstructor() throws Exception { - try { - beanFactory.getBean("constructor"); - fail("expected security exception"); - } catch (BeanCreationException ex) { - // expected - assertTrue(ex.getMostSpecificCause() instanceof SecurityException); - } - } - - @Test - public void testContainerPriviledges() throws Exception { - AccessControlContext acc = provider.getAccessControlContext(); - - AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { - - public Object run() throws Exception { - beanFactory.getBean("working-factory-method"); - beanFactory.getBean("container-execution"); - return null; - } - }, acc); - } - - @Test - public void testPropertyInjection() throws Exception { - try { - beanFactory.getBean("property-injection"); - fail("expected security exception"); - } catch (BeanCreationException ex) { - assertTrue(ex.getMessage().contains("security")); - } - - beanFactory.getBean("working-property-injection"); - } - - @Test - public void testInitSecurityAwarePrototypeBean() { - final DefaultListableBeanFactory lbf = new DefaultListableBeanFactory(); - BeanDefinitionBuilder bdb = BeanDefinitionBuilder - .genericBeanDefinition(NonPrivilegedBean.class).setScope( - ConfigurableBeanFactory.SCOPE_PROTOTYPE) - .setInitMethodName("init").setDestroyMethodName("destroy") - .addConstructorArgValue("user1"); - lbf.registerBeanDefinition("test", bdb.getBeanDefinition()); - final Subject subject = new Subject(); - subject.getPrincipals().add(new TestPrincipal("user1")); - - NonPrivilegedBean bean = Subject.doAsPrivileged( - subject, new PrivilegedAction<NonPrivilegedBean>() { - public NonPrivilegedBean run() { - return lbf.getBean("test", NonPrivilegedBean.class); - } - }, null); - assertNotNull(bean); - } - - @Test - public void testTrustedExecution() throws Exception { - beanFactory.setSecurityContextProvider(null); - - Permissions perms = new Permissions(); - perms.add(new AuthPermission("getSubject")); - ProtectionDomain pd = new ProtectionDomain(null, perms); - - AccessControlContext acc = new AccessControlContext( - new ProtectionDomain[] { pd }); - - final Subject subject = new Subject(); - subject.getPrincipals().add(new TestPrincipal("user1")); - - // request the beans from non-privileged code - Subject.doAsPrivileged(subject, new PrivilegedAction<Object>() { - - public Object run() { - // sanity check - assertEquals("user1", getCurrentSubjectName()); - assertEquals(false, NonPrivilegedBean.destroyed); - - beanFactory.getBean("trusted-spring-callbacks"); - beanFactory.getBean("trusted-custom-init-destroy"); - // the factory is a prototype - ask for multiple instances - beanFactory.getBean("trusted-spring-factory"); - beanFactory.getBean("trusted-spring-factory"); - beanFactory.getBean("trusted-spring-factory"); - - beanFactory.getBean("trusted-factory-bean"); - beanFactory.getBean("trusted-static-factory-method"); - beanFactory.getBean("trusted-factory-method"); - beanFactory.getBean("trusted-property-injection"); - beanFactory.getBean("trusted-working-property-injection"); - - beanFactory.destroySingletons(); - assertEquals(true, NonPrivilegedBean.destroyed); - return null; - } - }, provider.getAccessControlContext()); - } +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.factory.support.security; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNotNull; +import static junit.framework.Assert.assertNull; +import static junit.framework.Assert.assertTrue; +import static junit.framework.Assert.fail; + +import java.lang.reflect.Method; +import java.net.URL; +import java.security.AccessControlContext; +import java.security.AccessController; +import java.security.Permissions; +import java.security.Policy; +import java.security.Principal; +import java.security.PrivilegedAction; +import java.security.PrivilegedExceptionAction; +import java.security.ProtectionDomain; +import java.util.PropertyPermission; +import java.util.Set; + +import javax.security.auth.AuthPermission; +import javax.security.auth.Subject; + +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanClassLoaderAware; +import org.springframework.beans.factory.BeanCreationException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.BeanFactoryAware; +import org.springframework.beans.factory.BeanNameAware; +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.SmartFactoryBean; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.beans.factory.support.SecurityContextProvider; +import org.springframework.beans.factory.support.security.support.ConstructorBean; +import org.springframework.beans.factory.support.security.support.CustomCallbackBean; +import org.springframework.beans.factory.xml.XmlBeanFactory; +import org.springframework.core.io.DefaultResourceLoader; +import org.springframework.core.io.Resource; + +/** + * Security test case. Checks whether the container uses its privileges for its + * internal work but does not leak them when touching/calling user code. + * + *t The first half of the test case checks that permissions are downgraded when + * calling user code while the second half that the caller code permission get + * through and Spring doesn't override the permission stack. + * + * @author Costin Leau + */ +public class CallbacksSecurityTests { + + private XmlBeanFactory beanFactory; + private SecurityContextProvider provider; + + private static class NonPrivilegedBean { + + private String expectedName; + public static boolean destroyed = false; + + public NonPrivilegedBean(String expected) { + this.expectedName = expected; + checkCurrentContext(); + } + + public void init() { + checkCurrentContext(); + } + + public void destroy() { + checkCurrentContext(); + destroyed = true; + } + + public void setProperty(Object value) { + checkCurrentContext(); + } + + public Object getProperty() { + checkCurrentContext(); + return null; + } + + public void setListProperty(Object value) { + checkCurrentContext(); + } + + public Object getListProperty() { + checkCurrentContext(); + return null; + } + + private void checkCurrentContext() { + assertEquals(expectedName, getCurrentSubjectName()); + } + } + + private static class NonPrivilegedSpringCallbacksBean implements + InitializingBean, DisposableBean, BeanClassLoaderAware, + BeanFactoryAware, BeanNameAware { + + private String expectedName; + public static boolean destroyed = false; + + public NonPrivilegedSpringCallbacksBean(String expected) { + this.expectedName = expected; + checkCurrentContext(); + } + + public void afterPropertiesSet() { + checkCurrentContext(); + } + + public void destroy() { + checkCurrentContext(); + destroyed = true; + } + + public void setBeanName(String name) { + checkCurrentContext(); + } + + public void setBeanClassLoader(ClassLoader classLoader) { + checkCurrentContext(); + } + + public void setBeanFactory(BeanFactory beanFactory) + throws BeansException { + checkCurrentContext(); + } + + private void checkCurrentContext() { + assertEquals(expectedName, getCurrentSubjectName()); + } + } + + private static class NonPrivilegedFactoryBean implements SmartFactoryBean { + private String expectedName; + + public NonPrivilegedFactoryBean(String expected) { + this.expectedName = expected; + checkCurrentContext(); + } + + public boolean isEagerInit() { + checkCurrentContext(); + return false; + } + + public boolean isPrototype() { + checkCurrentContext(); + return true; + } + + public Object getObject() throws Exception { + checkCurrentContext(); + return new Object(); + } + + public Class getObjectType() { + checkCurrentContext(); + return Object.class; + } + + public boolean isSingleton() { + checkCurrentContext(); + return false; + } + + private void checkCurrentContext() { + assertEquals(expectedName, getCurrentSubjectName()); + } + } + + private static class NonPrivilegedFactory { + + private final String expectedName; + + public NonPrivilegedFactory(String expected) { + this.expectedName = expected; + assertEquals(expectedName, getCurrentSubjectName()); + } + + public static Object makeStaticInstance(String expectedName) { + assertEquals(expectedName, getCurrentSubjectName()); + return new Object(); + } + + public Object makeInstance() { + assertEquals(expectedName, getCurrentSubjectName()); + return new Object(); + } + } + + private static String getCurrentSubjectName() { + final AccessControlContext acc = AccessController.getContext(); + + return AccessController.doPrivileged(new PrivilegedAction<String>() { + + public String run() { + Subject subject = Subject.getSubject(acc); + if (subject == null) { + return null; + } + + Set<Principal> principals = subject.getPrincipals(); + + if (principals == null) { + return null; + } + for (Principal p : principals) { + return p.getName(); + } + return null; + } + }); + } + + private static class TestPrincipal implements Principal { + + private String name; + + public TestPrincipal(String name) { + this.name = name; + } + + public String getName() { + return this.name; + } + + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof TestPrincipal)) { + return false; + } + TestPrincipal p = (TestPrincipal) obj; + return this.name.equals(p.name); + } + + public int hashCode() { + return this.name.hashCode(); + } + } + + public CallbacksSecurityTests() { + // setup security + if (System.getSecurityManager() == null) { + Policy policy = Policy.getPolicy(); + URL policyURL = getClass() + .getResource( + "/org/springframework/beans/factory/support/security/policy.all"); + System.setProperty("java.security.policy", policyURL.toString()); + System.setProperty("policy.allowSystemProperty", "true"); + policy.refresh(); + + System.setSecurityManager(new SecurityManager()); + } + } + + @Before + public void setUp() throws Exception { + + final ProtectionDomain empty = new ProtectionDomain(null, + new Permissions()); + + provider = new SecurityContextProvider() { + private final AccessControlContext acc = new AccessControlContext( + new ProtectionDomain[] { empty }); + + public AccessControlContext getAccessControlContext() { + return acc; + } + }; + + DefaultResourceLoader drl = new DefaultResourceLoader(); + Resource config = drl + .getResource("/org/springframework/beans/factory/support/security/callbacks.xml"); + beanFactory = new XmlBeanFactory(config); + beanFactory.setSecurityContextProvider(provider); + } + + @Test + public void testSecuritySanity() throws Exception { + AccessControlContext acc = provider.getAccessControlContext(); + try { + acc.checkPermission(new PropertyPermission("*", "read")); + fail("Acc should not have any permissions"); + } catch (SecurityException se) { + // expected + } + + final CustomCallbackBean bean = new CustomCallbackBean(); + final Method method = bean.getClass().getMethod("destroy", null); + method.setAccessible(true); + + try { + AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { + + public Object run() throws Exception { + method.invoke(bean, null); + return null; + } + }, acc); + fail("expected security exception"); + } catch (Exception ex) { + } + + final Class<ConstructorBean> cl = ConstructorBean.class; + try { + AccessController.doPrivileged( + new PrivilegedExceptionAction<Object>() { + + public Object run() throws Exception { + return cl.newInstance(); + } + }, acc); + fail("expected security exception"); + } catch (Exception ex) { + } + } + + @Test + public void testSpringInitBean() throws Exception { + try { + beanFactory.getBean("spring-init"); + fail("expected security exception"); + } catch (BeanCreationException ex) { + assertTrue(ex.getCause() instanceof SecurityException); + } + } + + @Test + public void testCustomInitBean() throws Exception { + try { + beanFactory.getBean("custom-init"); + fail("expected security exception"); + } catch (BeanCreationException ex) { + assertTrue(ex.getCause() instanceof SecurityException); + } + } + + @Test + public void testSpringDestroyBean() throws Exception { + beanFactory.getBean("spring-destroy"); + beanFactory.destroySingletons(); + assertNull(System.getProperty("security.destroy")); + } + + @Test + public void testCustomDestroyBean() throws Exception { + beanFactory.getBean("custom-destroy"); + beanFactory.destroySingletons(); + assertNull(System.getProperty("security.destroy")); + } + + @Test + public void testCustomFactoryObject() throws Exception { + try { + beanFactory.getBean("spring-factory"); + fail("expected security exception"); + } catch (BeanCreationException ex) { + assertTrue(ex.getCause() instanceof SecurityException); + } + + } + + @Test + public void testCustomFactoryType() throws Exception { + assertNull(beanFactory.getType("spring-factory")); + assertNull(System.getProperty("factory.object.type")); + } + + @Test + public void testCustomStaticFactoryMethod() throws Exception { + try { + beanFactory.getBean("custom-static-factory-method"); + fail("expected security exception"); + } catch (BeanCreationException ex) { + assertTrue(ex.getMostSpecificCause() instanceof SecurityException); + } + } + + @Test + public void testCustomInstanceFactoryMethod() throws Exception { + try { + beanFactory.getBean("custom-factory-method"); + fail("expected security exception"); + } catch (BeanCreationException ex) { + assertTrue(ex.getMostSpecificCause() instanceof SecurityException); + } + } + + @Test + public void testTrustedFactoryMethod() throws Exception { + try { + beanFactory.getBean("privileged-static-factory-method"); + fail("expected security exception"); + } catch (BeanCreationException ex) { + assertTrue(ex.getMostSpecificCause() instanceof SecurityException); + } + } + + @Test + public void testConstructor() throws Exception { + try { + beanFactory.getBean("constructor"); + fail("expected security exception"); + } catch (BeanCreationException ex) { + // expected + assertTrue(ex.getMostSpecificCause() instanceof SecurityException); + } + } + + @Test + public void testContainerPriviledges() throws Exception { + AccessControlContext acc = provider.getAccessControlContext(); + + AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { + + public Object run() throws Exception { + beanFactory.getBean("working-factory-method"); + beanFactory.getBean("container-execution"); + return null; + } + }, acc); + } + + @Test + public void testPropertyInjection() throws Exception { + try { + beanFactory.getBean("property-injection"); + fail("expected security exception"); + } catch (BeanCreationException ex) { + assertTrue(ex.getMessage().contains("security")); + } + + beanFactory.getBean("working-property-injection"); + } + + @Test + public void testInitSecurityAwarePrototypeBean() { + final DefaultListableBeanFactory lbf = new DefaultListableBeanFactory(); + BeanDefinitionBuilder bdb = BeanDefinitionBuilder + .genericBeanDefinition(NonPrivilegedBean.class).setScope( + ConfigurableBeanFactory.SCOPE_PROTOTYPE) + .setInitMethodName("init").setDestroyMethodName("destroy") + .addConstructorArgValue("user1"); + lbf.registerBeanDefinition("test", bdb.getBeanDefinition()); + final Subject subject = new Subject(); + subject.getPrincipals().add(new TestPrincipal("user1")); + + NonPrivilegedBean bean = Subject.doAsPrivileged( + subject, new PrivilegedAction<NonPrivilegedBean>() { + public NonPrivilegedBean run() { + return lbf.getBean("test", NonPrivilegedBean.class); + } + }, null); + assertNotNull(bean); + } + + @Test + public void testTrustedExecution() throws Exception { + beanFactory.setSecurityContextProvider(null); + + Permissions perms = new Permissions(); + perms.add(new AuthPermission("getSubject")); + ProtectionDomain pd = new ProtectionDomain(null, perms); + + AccessControlContext acc = new AccessControlContext( + new ProtectionDomain[] { pd }); + + final Subject subject = new Subject(); + subject.getPrincipals().add(new TestPrincipal("user1")); + + // request the beans from non-privileged code + Subject.doAsPrivileged(subject, new PrivilegedAction<Object>() { + + public Object run() { + // sanity check + assertEquals("user1", getCurrentSubjectName()); + assertEquals(false, NonPrivilegedBean.destroyed); + + beanFactory.getBean("trusted-spring-callbacks"); + beanFactory.getBean("trusted-custom-init-destroy"); + // the factory is a prototype - ask for multiple instances + beanFactory.getBean("trusted-spring-factory"); + beanFactory.getBean("trusted-spring-factory"); + beanFactory.getBean("trusted-spring-factory"); + + beanFactory.getBean("trusted-factory-bean"); + beanFactory.getBean("trusted-static-factory-method"); + beanFactory.getBean("trusted-factory-method"); + beanFactory.getBean("trusted-property-injection"); + beanFactory.getBean("trusted-working-property-injection"); + + beanFactory.destroySingletons(); + assertEquals(true, NonPrivilegedBean.destroyed); + return null; + } + }, provider.getAccessControlContext()); + } } \ No newline at end of file diff --git a/org.springframework.beans/src/test/java/org/springframework/beans/factory/support/security/policy.all b/org.springframework.beans/src/test/java/org/springframework/beans/factory/support/security/policy.all index a59033804b8..de8e185c945 100644 --- a/org.springframework.beans/src/test/java/org/springframework/beans/factory/support/security/policy.all +++ b/org.springframework.beans/src/test/java/org/springframework/beans/factory/support/security/policy.all @@ -1,3 +1,3 @@ -grant { - permission java.security.AllPermission; +grant { + permission java.security.AllPermission; }; \ No newline at end of file diff --git a/org.springframework.beans/src/test/java/org/springframework/beans/factory/support/security/support/ConstructorBean.java b/org.springframework.beans/src/test/java/org/springframework/beans/factory/support/security/support/ConstructorBean.java index 1934157b94f..95cf5df4dab 100644 --- a/org.springframework.beans/src/test/java/org/springframework/beans/factory/support/security/support/ConstructorBean.java +++ b/org.springframework.beans/src/test/java/org/springframework/beans/factory/support/security/support/ConstructorBean.java @@ -1,30 +1,30 @@ -/* - * Copyright 2006-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.beans.factory.support.security.support; - -/** - * @author Costin Leau - */ -public class ConstructorBean { - - public ConstructorBean() { - System.getProperties(); - } - - public ConstructorBean(Object obj) { - System.out.println("Received object " + obj); - } -} +/* + * Copyright 2006-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.beans.factory.support.security.support; + +/** + * @author Costin Leau + */ +public class ConstructorBean { + + public ConstructorBean() { + System.getProperties(); + } + + public ConstructorBean(Object obj) { + System.out.println("Received object " + obj); + } +} diff --git a/org.springframework.beans/src/test/java/org/springframework/beans/factory/support/security/support/CustomCallbackBean.java b/org.springframework.beans/src/test/java/org/springframework/beans/factory/support/security/support/CustomCallbackBean.java index c64000093b2..80c09aff2bd 100644 --- a/org.springframework.beans/src/test/java/org/springframework/beans/factory/support/security/support/CustomCallbackBean.java +++ b/org.springframework.beans/src/test/java/org/springframework/beans/factory/support/security/support/CustomCallbackBean.java @@ -1,30 +1,30 @@ -/* - * Copyright 2006-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.beans.factory.support.security.support; - -/** - * @author Costin Leau - */ -public class CustomCallbackBean { - - public void init() { - System.getProperties(); - } - - public void destroy() { - System.setProperty("security.destroy", "true"); - } -} +/* + * Copyright 2006-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.beans.factory.support.security.support; + +/** + * @author Costin Leau + */ +public class CustomCallbackBean { + + public void init() { + System.getProperties(); + } + + public void destroy() { + System.setProperty("security.destroy", "true"); + } +} diff --git a/org.springframework.beans/src/test/java/org/springframework/beans/factory/support/security/support/CustomFactoryBean.java b/org.springframework.beans/src/test/java/org/springframework/beans/factory/support/security/support/CustomFactoryBean.java index 231c5d1d089..93a8c344ba9 100644 --- a/org.springframework.beans/src/test/java/org/springframework/beans/factory/support/security/support/CustomFactoryBean.java +++ b/org.springframework.beans/src/test/java/org/springframework/beans/factory/support/security/support/CustomFactoryBean.java @@ -1,39 +1,39 @@ -/* - * Copyright 2006-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.beans.factory.support.security.support; - -import java.util.Properties; - -import org.springframework.beans.factory.FactoryBean; - -/** - * @author Costin Leau - */ -public class CustomFactoryBean implements FactoryBean<Object> { - - public Object getObject() throws Exception { - return System.getProperties(); - } - - public Class getObjectType() { - System.setProperty("factory.object.type", "true"); - return Properties.class; - } - - public boolean isSingleton() { - return true; - } -} +/* + * Copyright 2006-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.beans.factory.support.security.support; + +import java.util.Properties; + +import org.springframework.beans.factory.FactoryBean; + +/** + * @author Costin Leau + */ +public class CustomFactoryBean implements FactoryBean<Object> { + + public Object getObject() throws Exception { + return System.getProperties(); + } + + public Class getObjectType() { + System.setProperty("factory.object.type", "true"); + return Properties.class; + } + + public boolean isSingleton() { + return true; + } +} diff --git a/org.springframework.beans/src/test/java/org/springframework/beans/factory/support/security/support/DestroyBean.java b/org.springframework.beans/src/test/java/org/springframework/beans/factory/support/security/support/DestroyBean.java index da25e799b74..d24ff224741 100644 --- a/org.springframework.beans/src/test/java/org/springframework/beans/factory/support/security/support/DestroyBean.java +++ b/org.springframework.beans/src/test/java/org/springframework/beans/factory/support/security/support/DestroyBean.java @@ -1,28 +1,28 @@ -/* - * Copyright 2006-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.beans.factory.support.security.support; - -import org.springframework.beans.factory.DisposableBean; - -/** - * @author Costin Leau - */ -public class DestroyBean implements DisposableBean { - - public void destroy() throws Exception { - System.setProperty("security.destroy", "true"); - } -} +/* + * Copyright 2006-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.beans.factory.support.security.support; + +import org.springframework.beans.factory.DisposableBean; + +/** + * @author Costin Leau + */ +public class DestroyBean implements DisposableBean { + + public void destroy() throws Exception { + System.setProperty("security.destroy", "true"); + } +} diff --git a/org.springframework.beans/src/test/java/org/springframework/beans/factory/support/security/support/FactoryBean.java b/org.springframework.beans/src/test/java/org/springframework/beans/factory/support/security/support/FactoryBean.java index 80871674f5c..43efd6fd8b0 100644 --- a/org.springframework.beans/src/test/java/org/springframework/beans/factory/support/security/support/FactoryBean.java +++ b/org.springframework.beans/src/test/java/org/springframework/beans/factory/support/security/support/FactoryBean.java @@ -1,36 +1,36 @@ -/* - * Copyright 2006-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.beans.factory.support.security.support; - -/** - * @author Costin Leau - */ -public class FactoryBean { - - public static Object makeStaticInstance() { - System.getProperties(); - return new Object(); - } - - protected static Object protectedStaticInstance() { - return "protectedStaticInstance"; - } - - public Object makeInstance() { - System.getProperties(); - return new Object(); - } -} +/* + * Copyright 2006-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.beans.factory.support.security.support; + +/** + * @author Costin Leau + */ +public class FactoryBean { + + public static Object makeStaticInstance() { + System.getProperties(); + return new Object(); + } + + protected static Object protectedStaticInstance() { + return "protectedStaticInstance"; + } + + public Object makeInstance() { + System.getProperties(); + return new Object(); + } +} diff --git a/org.springframework.beans/src/test/java/org/springframework/beans/factory/support/security/support/InitBean.java b/org.springframework.beans/src/test/java/org/springframework/beans/factory/support/security/support/InitBean.java index 0c3f71e63ec..acd4343d21c 100644 --- a/org.springframework.beans/src/test/java/org/springframework/beans/factory/support/security/support/InitBean.java +++ b/org.springframework.beans/src/test/java/org/springframework/beans/factory/support/security/support/InitBean.java @@ -1,28 +1,28 @@ -/* - * Copyright 2006-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.beans.factory.support.security.support; - -import org.springframework.beans.factory.InitializingBean; - -/** - * @author Costin Leau - */ -public class InitBean implements InitializingBean { - - public void afterPropertiesSet() throws Exception { - System.getProperties(); - } -} +/* + * Copyright 2006-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.beans.factory.support.security.support; + +import org.springframework.beans.factory.InitializingBean; + +/** + * @author Costin Leau + */ +public class InitBean implements InitializingBean { + + public void afterPropertiesSet() throws Exception { + System.getProperties(); + } +} diff --git a/org.springframework.beans/src/test/java/org/springframework/beans/factory/support/security/support/PropertyBean.java b/org.springframework.beans/src/test/java/org/springframework/beans/factory/support/security/support/PropertyBean.java index 494187c20f7..ced0d45b93b 100644 --- a/org.springframework.beans/src/test/java/org/springframework/beans/factory/support/security/support/PropertyBean.java +++ b/org.springframework.beans/src/test/java/org/springframework/beans/factory/support/security/support/PropertyBean.java @@ -1,30 +1,30 @@ -/* - * Copyright 2006-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.beans.factory.support.security.support; - -/** - * @author Costin Leau - */ -public class PropertyBean { - - public void setSecurityProperty(Object property) { - System.getProperties(); - } - - public void setProperty(Object property) { - - } -} +/* + * Copyright 2006-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.beans.factory.support.security.support; + +/** + * @author Costin Leau + */ +public class PropertyBean { + + public void setSecurityProperty(Object property) { + System.getProperties(); + } + + public void setProperty(Object property) { + + } +} diff --git a/org.springframework.beans/src/test/java/test/beans/DummyBean.java b/org.springframework.beans/src/test/java/test/beans/DummyBean.java index 0fda3dc3e79..54ae5e65d6d 100644 --- a/org.springframework.beans/src/test/java/test/beans/DummyBean.java +++ b/org.springframework.beans/src/test/java/test/beans/DummyBean.java @@ -1,68 +1,68 @@ -/* - * Copyright 2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package test.beans; - -/** - * @author Costin Leau - */ -public class DummyBean { - - private Object value; - private String name; - private int age; - private TestBean spouse; - - public DummyBean(Object value) { - this.value = value; - } - - public DummyBean(String name, int age) { - this.name = name; - this.age = age; - } - - public DummyBean(int ageRef, String nameRef) { - this.name = nameRef; - this.age = ageRef; - } - - public DummyBean(String name, TestBean spouse) { - this.name = name; - this.spouse = spouse; - } - - public DummyBean(String name, Object value, int age) { - this.name = name; - this.value = value; - this.age = age; - } - - public Object getValue() { - return value; - } - - public String getName() { - return name; - } - - public int getAge() { - return age; - } - - public TestBean getSpouse() { - return spouse; - } -} +/* + * Copyright 2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package test.beans; + +/** + * @author Costin Leau + */ +public class DummyBean { + + private Object value; + private String name; + private int age; + private TestBean spouse; + + public DummyBean(Object value) { + this.value = value; + } + + public DummyBean(String name, int age) { + this.name = name; + this.age = age; + } + + public DummyBean(int ageRef, String nameRef) { + this.name = nameRef; + this.age = ageRef; + } + + public DummyBean(String name, TestBean spouse) { + this.name = name; + this.spouse = spouse; + } + + public DummyBean(String name, Object value, int age) { + this.name = name; + this.value = value; + this.age = age; + } + + public Object getValue() { + return value; + } + + public String getName() { + return name; + } + + public int getAge() { + return age; + } + + public TestBean getSpouse() { + return spouse; + } +} diff --git a/org.springframework.context.support/.settings/org.eclipse.jdt.ui.prefs b/org.springframework.context.support/.settings/org.eclipse.jdt.ui.prefs index 09becb34db6..5ffc725a5ae 100644 --- a/org.springframework.context.support/.settings/org.eclipse.jdt.ui.prefs +++ b/org.springframework.context.support/.settings/org.eclipse.jdt.ui.prefs @@ -1,4 +1,4 @@ -#Wed Mar 31 18:40:01 EEST 2010 -eclipse.preferences.version=1 -formatter_profile=_Spring -formatter_settings_version=11 +#Wed Mar 31 18:40:01 EEST 2010 +eclipse.preferences.version=1 +formatter_profile=_Spring +formatter_settings_version=11 diff --git a/org.springframework.context.support/src/main/java/org/springframework/scheduling/commonj/TimerManagerAccessor.java b/org.springframework.context.support/src/main/java/org/springframework/scheduling/commonj/TimerManagerAccessor.java index f53108cec24..46db6ee2c09 100644 --- a/org.springframework.context.support/src/main/java/org/springframework/scheduling/commonj/TimerManagerAccessor.java +++ b/org.springframework.context.support/src/main/java/org/springframework/scheduling/commonj/TimerManagerAccessor.java @@ -1,163 +1,163 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.scheduling.commonj; - -import javax.naming.NamingException; - -import commonj.timers.TimerManager; - -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.context.Lifecycle; -import org.springframework.jndi.JndiLocatorSupport; - -/** - * Base class for classes that are accessing a CommonJ {@link commonj.timers.TimerManager} - * Defines common configuration settings and common lifecycle handling. - * - * @author Juergen Hoeller - * @since 3.0 - * @see commonj.timers.TimerManager - */ -public abstract class TimerManagerAccessor extends JndiLocatorSupport - implements InitializingBean, DisposableBean, Lifecycle { - - private TimerManager timerManager; - - private String timerManagerName; - - private boolean shared = false; - - - /** - * Specify the CommonJ TimerManager to delegate to. - * <p>Note that the given TimerManager's lifecycle will be managed - * by this FactoryBean. - * <p>Alternatively (and typically), you can specify the JNDI name - * of the target TimerManager. - * @see #setTimerManagerName - */ - public void setTimerManager(TimerManager timerManager) { - this.timerManager = timerManager; - } - - /** - * Set the JNDI name of the CommonJ TimerManager. - * <p>This can either be a fully qualified JNDI name, or the JNDI name relative - * to the current environment naming context if "resourceRef" is set to "true". - * @see #setTimerManager - * @see #setResourceRef - */ - public void setTimerManagerName(String timerManagerName) { - this.timerManagerName = timerManagerName; - } - - /** - * Specify whether the TimerManager obtained by this FactoryBean - * is a shared instance ("true") or an independent instance ("false"). - * The lifecycle of the former is supposed to be managed by the application - * server, while the lifecycle of the latter is up to the application. - * <p>Default is "false", i.e. managing an independent TimerManager instance. - * This is what the CommonJ specification suggests that application servers - * are supposed to offer via JNDI lookups, typically declared as a - * <code>resource-ref</code> of type <code>commonj.timers.TimerManager</code> - * in <code>web.xml<code>, with <code>res-sharing-scope</code> set to 'Unshareable'. - * <p>Switch this flag to "true" if you are obtaining a shared TimerManager, - * typically through specifying the JNDI location of a TimerManager that - * has been explicitly declared as 'Shareable'. Note that WebLogic's - * cluster-aware Job Scheduler is a shared TimerManager too. - * <p>The sole difference between this FactoryBean being in shared or - * non-shared mode is that it will only attempt to suspend / resume / stop - * the underlying TimerManager in case of an independent (non-shared) instance. - * This only affects the {@link org.springframework.context.Lifecycle} support - * as well as application context shutdown. - * @see #stop() - * @see #start() - * @see #destroy() - * @see commonj.timers.TimerManager - */ - public void setShared(boolean shared) { - this.shared = shared; - } - - - public void afterPropertiesSet() throws NamingException { - if (this.timerManager == null) { - if (this.timerManagerName == null) { - throw new IllegalArgumentException("Either 'timerManager' or 'timerManagerName' must be specified"); - } - this.timerManager = lookup(this.timerManagerName, TimerManager.class); - } - } - - protected final TimerManager getTimerManager() { - return this.timerManager; - } - - - //--------------------------------------------------------------------- - // Implementation of Lifecycle interface - //--------------------------------------------------------------------- - - /** - * Resumes the underlying TimerManager (if not shared). - * @see commonj.timers.TimerManager#resume() - */ - public void start() { - if (!this.shared) { - this.timerManager.resume(); - } - } - - /** - * Suspends the underlying TimerManager (if not shared). - * @see commonj.timers.TimerManager#suspend() - */ - public void stop() { - if (!this.shared) { - this.timerManager.suspend(); - } - } - - /** - * Considers the underlying TimerManager as running if it is - * neither suspending nor stopping. - * @see commonj.timers.TimerManager#isSuspending() - * @see commonj.timers.TimerManager#isStopping() - */ - public boolean isRunning() { - return (!this.timerManager.isSuspending() && !this.timerManager.isStopping()); - } - - - //--------------------------------------------------------------------- - // Implementation of DisposableBean interface - //--------------------------------------------------------------------- - - /** - * Stops the underlying TimerManager (if not shared). - * @see commonj.timers.TimerManager#stop() - */ - public void destroy() { - // Stop the entire TimerManager, if necessary. - if (!this.shared) { - // May return early, but at least we already cancelled all known Timers. - this.timerManager.stop(); - } - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.scheduling.commonj; + +import javax.naming.NamingException; + +import commonj.timers.TimerManager; + +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.context.Lifecycle; +import org.springframework.jndi.JndiLocatorSupport; + +/** + * Base class for classes that are accessing a CommonJ {@link commonj.timers.TimerManager} + * Defines common configuration settings and common lifecycle handling. + * + * @author Juergen Hoeller + * @since 3.0 + * @see commonj.timers.TimerManager + */ +public abstract class TimerManagerAccessor extends JndiLocatorSupport + implements InitializingBean, DisposableBean, Lifecycle { + + private TimerManager timerManager; + + private String timerManagerName; + + private boolean shared = false; + + + /** + * Specify the CommonJ TimerManager to delegate to. + * <p>Note that the given TimerManager's lifecycle will be managed + * by this FactoryBean. + * <p>Alternatively (and typically), you can specify the JNDI name + * of the target TimerManager. + * @see #setTimerManagerName + */ + public void setTimerManager(TimerManager timerManager) { + this.timerManager = timerManager; + } + + /** + * Set the JNDI name of the CommonJ TimerManager. + * <p>This can either be a fully qualified JNDI name, or the JNDI name relative + * to the current environment naming context if "resourceRef" is set to "true". + * @see #setTimerManager + * @see #setResourceRef + */ + public void setTimerManagerName(String timerManagerName) { + this.timerManagerName = timerManagerName; + } + + /** + * Specify whether the TimerManager obtained by this FactoryBean + * is a shared instance ("true") or an independent instance ("false"). + * The lifecycle of the former is supposed to be managed by the application + * server, while the lifecycle of the latter is up to the application. + * <p>Default is "false", i.e. managing an independent TimerManager instance. + * This is what the CommonJ specification suggests that application servers + * are supposed to offer via JNDI lookups, typically declared as a + * <code>resource-ref</code> of type <code>commonj.timers.TimerManager</code> + * in <code>web.xml<code>, with <code>res-sharing-scope</code> set to 'Unshareable'. + * <p>Switch this flag to "true" if you are obtaining a shared TimerManager, + * typically through specifying the JNDI location of a TimerManager that + * has been explicitly declared as 'Shareable'. Note that WebLogic's + * cluster-aware Job Scheduler is a shared TimerManager too. + * <p>The sole difference between this FactoryBean being in shared or + * non-shared mode is that it will only attempt to suspend / resume / stop + * the underlying TimerManager in case of an independent (non-shared) instance. + * This only affects the {@link org.springframework.context.Lifecycle} support + * as well as application context shutdown. + * @see #stop() + * @see #start() + * @see #destroy() + * @see commonj.timers.TimerManager + */ + public void setShared(boolean shared) { + this.shared = shared; + } + + + public void afterPropertiesSet() throws NamingException { + if (this.timerManager == null) { + if (this.timerManagerName == null) { + throw new IllegalArgumentException("Either 'timerManager' or 'timerManagerName' must be specified"); + } + this.timerManager = lookup(this.timerManagerName, TimerManager.class); + } + } + + protected final TimerManager getTimerManager() { + return this.timerManager; + } + + + //--------------------------------------------------------------------- + // Implementation of Lifecycle interface + //--------------------------------------------------------------------- + + /** + * Resumes the underlying TimerManager (if not shared). + * @see commonj.timers.TimerManager#resume() + */ + public void start() { + if (!this.shared) { + this.timerManager.resume(); + } + } + + /** + * Suspends the underlying TimerManager (if not shared). + * @see commonj.timers.TimerManager#suspend() + */ + public void stop() { + if (!this.shared) { + this.timerManager.suspend(); + } + } + + /** + * Considers the underlying TimerManager as running if it is + * neither suspending nor stopping. + * @see commonj.timers.TimerManager#isSuspending() + * @see commonj.timers.TimerManager#isStopping() + */ + public boolean isRunning() { + return (!this.timerManager.isSuspending() && !this.timerManager.isStopping()); + } + + + //--------------------------------------------------------------------- + // Implementation of DisposableBean interface + //--------------------------------------------------------------------- + + /** + * Stops the underlying TimerManager (if not shared). + * @see commonj.timers.TimerManager#stop() + */ + public void destroy() { + // Stop the entire TimerManager, if necessary. + if (!this.shared) { + // May return early, but at least we already cancelled all known Timers. + this.timerManager.stop(); + } + } + +} diff --git a/org.springframework.context.support/src/main/java/org/springframework/scheduling/commonj/TimerManagerTaskScheduler.java b/org.springframework.context.support/src/main/java/org/springframework/scheduling/commonj/TimerManagerTaskScheduler.java index d9cba9e5b82..8d0f0795bc5 100644 --- a/org.springframework.context.support/src/main/java/org/springframework/scheduling/commonj/TimerManagerTaskScheduler.java +++ b/org.springframework.context.support/src/main/java/org/springframework/scheduling/commonj/TimerManagerTaskScheduler.java @@ -1,174 +1,174 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.scheduling.commonj; - -import java.util.Date; -import java.util.concurrent.Delayed; -import java.util.concurrent.FutureTask; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; - -import commonj.timers.Timer; -import commonj.timers.TimerListener; - -import org.springframework.scheduling.TaskScheduler; -import org.springframework.scheduling.Trigger; -import org.springframework.scheduling.support.SimpleTriggerContext; -import org.springframework.scheduling.support.TaskUtils; -import org.springframework.util.ErrorHandler; - -/** - * Implementation of Spring's {@link TaskScheduler} interface, wrapping - * a CommonJ {@link commonj.timers.TimerManager}. - * - * @author Juergen Hoeller - * @author Mark Fisher - * @since 3.0 - */ -public class TimerManagerTaskScheduler extends TimerManagerAccessor implements TaskScheduler { - - private volatile ErrorHandler errorHandler; - - public void setErrorHandler(ErrorHandler errorHandler) { - this.errorHandler = errorHandler; - } - - public ScheduledFuture schedule(Runnable task, Trigger trigger) { - return new ReschedulingTimerListener(errorHandlingTask(task, true), trigger).schedule(); - } - - public ScheduledFuture schedule(Runnable task, Date startTime) { - TimerScheduledFuture futureTask = new TimerScheduledFuture(errorHandlingTask(task, false)); - Timer timer = getTimerManager().schedule(futureTask, startTime); - futureTask.setTimer(timer); - return futureTask; - } - - public ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period) { - TimerScheduledFuture futureTask = new TimerScheduledFuture(errorHandlingTask(task, true)); - Timer timer = getTimerManager().scheduleAtFixedRate(futureTask, startTime, period); - futureTask.setTimer(timer); - return futureTask; - } - - public ScheduledFuture scheduleAtFixedRate(Runnable task, long period) { - TimerScheduledFuture futureTask = new TimerScheduledFuture(errorHandlingTask(task, true)); - Timer timer = getTimerManager().scheduleAtFixedRate(futureTask, 0, period); - futureTask.setTimer(timer); - return futureTask; - } - - public ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay) { - TimerScheduledFuture futureTask = new TimerScheduledFuture(errorHandlingTask(task, true)); - Timer timer = getTimerManager().schedule(futureTask, startTime, delay); - futureTask.setTimer(timer); - return futureTask; - } - - public ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay) { - TimerScheduledFuture futureTask = new TimerScheduledFuture(errorHandlingTask(task, true)); - Timer timer = getTimerManager().schedule(futureTask, 0, delay); - futureTask.setTimer(timer); - return futureTask; - } - - private Runnable errorHandlingTask(Runnable delegate, boolean isRepeatingTask) { - return TaskUtils.decorateTaskWithErrorHandler(delegate, this.errorHandler, isRepeatingTask); - } - - - /** - * ScheduledFuture adapter that wraps a CommonJ Timer. - */ - private static class TimerScheduledFuture extends FutureTask<Object> implements TimerListener, ScheduledFuture<Object> { - - protected transient Timer timer; - - protected transient boolean cancelled = false; - - public TimerScheduledFuture(Runnable runnable) { - super(runnable, null); - } - - public void setTimer(Timer timer) { - this.timer = timer; - } - - public void timerExpired(Timer timer) { - runAndReset(); - } - - @Override - public boolean cancel(boolean mayInterruptIfRunning) { - boolean result = super.cancel(mayInterruptIfRunning); - this.timer.cancel(); - this.cancelled = true; - return result; - } - - public long getDelay(TimeUnit unit) { - return unit.convert(System.currentTimeMillis() - this.timer.getScheduledExecutionTime(), TimeUnit.MILLISECONDS); - } - - public int compareTo(Delayed other) { - if (this == other) { - return 0; - } - long diff = getDelay(TimeUnit.MILLISECONDS) - other.getDelay(TimeUnit.MILLISECONDS); - return (diff == 0 ? 0 : ((diff < 0)? -1 : 1)); - } - } - - - /** - * ScheduledFuture adapter for trigger-based rescheduling. - */ - private class ReschedulingTimerListener extends TimerScheduledFuture { - - private final Trigger trigger; - - private final SimpleTriggerContext triggerContext = new SimpleTriggerContext(); - - private volatile Date scheduledExecutionTime; - - public ReschedulingTimerListener(Runnable runnable, Trigger trigger) { - super(runnable); - this.trigger = trigger; - } - - public ScheduledFuture schedule() { - this.scheduledExecutionTime = this.trigger.nextExecutionTime(this.triggerContext); - if (this.scheduledExecutionTime == null) { - return null; - } - setTimer(getTimerManager().schedule(this, this.scheduledExecutionTime)); - return this; - } - - @Override - public void timerExpired(Timer timer) { - Date actualExecutionTime = new Date(); - super.timerExpired(timer); - Date completionTime = new Date(); - this.triggerContext.update(this.scheduledExecutionTime, actualExecutionTime, completionTime); - if (!this.cancelled) { - schedule(); - } - } - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.scheduling.commonj; + +import java.util.Date; +import java.util.concurrent.Delayed; +import java.util.concurrent.FutureTask; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +import commonj.timers.Timer; +import commonj.timers.TimerListener; + +import org.springframework.scheduling.TaskScheduler; +import org.springframework.scheduling.Trigger; +import org.springframework.scheduling.support.SimpleTriggerContext; +import org.springframework.scheduling.support.TaskUtils; +import org.springframework.util.ErrorHandler; + +/** + * Implementation of Spring's {@link TaskScheduler} interface, wrapping + * a CommonJ {@link commonj.timers.TimerManager}. + * + * @author Juergen Hoeller + * @author Mark Fisher + * @since 3.0 + */ +public class TimerManagerTaskScheduler extends TimerManagerAccessor implements TaskScheduler { + + private volatile ErrorHandler errorHandler; + + public void setErrorHandler(ErrorHandler errorHandler) { + this.errorHandler = errorHandler; + } + + public ScheduledFuture schedule(Runnable task, Trigger trigger) { + return new ReschedulingTimerListener(errorHandlingTask(task, true), trigger).schedule(); + } + + public ScheduledFuture schedule(Runnable task, Date startTime) { + TimerScheduledFuture futureTask = new TimerScheduledFuture(errorHandlingTask(task, false)); + Timer timer = getTimerManager().schedule(futureTask, startTime); + futureTask.setTimer(timer); + return futureTask; + } + + public ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period) { + TimerScheduledFuture futureTask = new TimerScheduledFuture(errorHandlingTask(task, true)); + Timer timer = getTimerManager().scheduleAtFixedRate(futureTask, startTime, period); + futureTask.setTimer(timer); + return futureTask; + } + + public ScheduledFuture scheduleAtFixedRate(Runnable task, long period) { + TimerScheduledFuture futureTask = new TimerScheduledFuture(errorHandlingTask(task, true)); + Timer timer = getTimerManager().scheduleAtFixedRate(futureTask, 0, period); + futureTask.setTimer(timer); + return futureTask; + } + + public ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay) { + TimerScheduledFuture futureTask = new TimerScheduledFuture(errorHandlingTask(task, true)); + Timer timer = getTimerManager().schedule(futureTask, startTime, delay); + futureTask.setTimer(timer); + return futureTask; + } + + public ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay) { + TimerScheduledFuture futureTask = new TimerScheduledFuture(errorHandlingTask(task, true)); + Timer timer = getTimerManager().schedule(futureTask, 0, delay); + futureTask.setTimer(timer); + return futureTask; + } + + private Runnable errorHandlingTask(Runnable delegate, boolean isRepeatingTask) { + return TaskUtils.decorateTaskWithErrorHandler(delegate, this.errorHandler, isRepeatingTask); + } + + + /** + * ScheduledFuture adapter that wraps a CommonJ Timer. + */ + private static class TimerScheduledFuture extends FutureTask<Object> implements TimerListener, ScheduledFuture<Object> { + + protected transient Timer timer; + + protected transient boolean cancelled = false; + + public TimerScheduledFuture(Runnable runnable) { + super(runnable, null); + } + + public void setTimer(Timer timer) { + this.timer = timer; + } + + public void timerExpired(Timer timer) { + runAndReset(); + } + + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + boolean result = super.cancel(mayInterruptIfRunning); + this.timer.cancel(); + this.cancelled = true; + return result; + } + + public long getDelay(TimeUnit unit) { + return unit.convert(System.currentTimeMillis() - this.timer.getScheduledExecutionTime(), TimeUnit.MILLISECONDS); + } + + public int compareTo(Delayed other) { + if (this == other) { + return 0; + } + long diff = getDelay(TimeUnit.MILLISECONDS) - other.getDelay(TimeUnit.MILLISECONDS); + return (diff == 0 ? 0 : ((diff < 0)? -1 : 1)); + } + } + + + /** + * ScheduledFuture adapter for trigger-based rescheduling. + */ + private class ReschedulingTimerListener extends TimerScheduledFuture { + + private final Trigger trigger; + + private final SimpleTriggerContext triggerContext = new SimpleTriggerContext(); + + private volatile Date scheduledExecutionTime; + + public ReschedulingTimerListener(Runnable runnable, Trigger trigger) { + super(runnable); + this.trigger = trigger; + } + + public ScheduledFuture schedule() { + this.scheduledExecutionTime = this.trigger.nextExecutionTime(this.triggerContext); + if (this.scheduledExecutionTime == null) { + return null; + } + setTimer(getTimerManager().schedule(this, this.scheduledExecutionTime)); + return this; + } + + @Override + public void timerExpired(Timer timer) { + Date actualExecutionTime = new Date(); + super.timerExpired(timer); + Date completionTime = new Date(); + this.triggerContext.update(this.scheduledExecutionTime, actualExecutionTime, completionTime); + if (!this.cancelled) { + schedule(); + } + } + } + +} diff --git a/org.springframework.context/src/main/java/org/springframework/context/EmbeddedValueResolverAware.java b/org.springframework.context/src/main/java/org/springframework/context/EmbeddedValueResolverAware.java index a3f3a0ce2f9..98d25eaaff8 100644 --- a/org.springframework.context/src/main/java/org/springframework/context/EmbeddedValueResolverAware.java +++ b/org.springframework.context/src/main/java/org/springframework/context/EmbeddedValueResolverAware.java @@ -1,41 +1,41 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.context; - -import org.springframework.beans.factory.Aware; -import org.springframework.util.StringValueResolver; - -/** - * Interface to be implemented by any object that wishes to be notified of a - * <b>StringValueResolver</b> for the <b> resolution of embedded definition values. - * - * <p>This is an alternative to a full ConfigurableBeanFactory dependency via the - * ApplicationContextAware/BeanFactoryAware interfaces. - * - * @author Juergen Hoeller - * @author Chris Beams - * @since 3.0.3 - * @see org.springframework.beans.factory.config.ConfigurableBeanFactory#resolveEmbeddedValue - */ -public interface EmbeddedValueResolverAware extends Aware { - - /** - * Set the StringValueResolver to use for resolving embedded definition values. - */ - void setEmbeddedValueResolver(StringValueResolver resolver); - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.context; + +import org.springframework.beans.factory.Aware; +import org.springframework.util.StringValueResolver; + +/** + * Interface to be implemented by any object that wishes to be notified of a + * <b>StringValueResolver</b> for the <b> resolution of embedded definition values. + * + * <p>This is an alternative to a full ConfigurableBeanFactory dependency via the + * ApplicationContextAware/BeanFactoryAware interfaces. + * + * @author Juergen Hoeller + * @author Chris Beams + * @since 3.0.3 + * @see org.springframework.beans.factory.config.ConfigurableBeanFactory#resolveEmbeddedValue + */ +public interface EmbeddedValueResolverAware extends Aware { + + /** + * Set the StringValueResolver to use for resolving embedded definition values. + */ + void setEmbeddedValueResolver(StringValueResolver resolver); + +} diff --git a/org.springframework.context/src/main/java/org/springframework/context/annotation/AnnotatedBeanDefinitionReader.java b/org.springframework.context/src/main/java/org/springframework/context/annotation/AnnotatedBeanDefinitionReader.java index 3986803b157..2d3ee5ab8ea 100644 --- a/org.springframework.context/src/main/java/org/springframework/context/annotation/AnnotatedBeanDefinitionReader.java +++ b/org.springframework.context/src/main/java/org/springframework/context/annotation/AnnotatedBeanDefinitionReader.java @@ -1,177 +1,177 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.context.annotation; - -import java.lang.annotation.Annotation; - -import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition; -import org.springframework.beans.factory.config.BeanDefinitionHolder; -import org.springframework.beans.factory.support.AutowireCandidateQualifier; -import org.springframework.beans.factory.support.BeanDefinitionReaderUtils; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.beans.factory.support.BeanNameGenerator; -import org.springframework.core.env.Environment; -import org.springframework.core.env.EnvironmentCapable; -import org.springframework.core.env.StandardEnvironment; -import org.springframework.core.type.AnnotationMetadata; -import org.springframework.util.Assert; - -/** - * Convenient adapter for programmatic registration of annotated bean classes. - * This is an alternative to {@link ClassPathBeanDefinitionScanner}, applying - * the same resolution of annotations but for explicitly registered classes only. - * - * @author Juergen Hoeller - * @author Chris Beams - * @author Sam Brannen - * @since 3.0 - * @see AnnotationConfigApplicationContext#register - */ -public class AnnotatedBeanDefinitionReader { - - private final BeanDefinitionRegistry registry; - - private Environment environment; - - private BeanNameGenerator beanNameGenerator = new AnnotationBeanNameGenerator(); - - private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver(); - - /** - * Create a new {@code AnnotatedBeanDefinitionReader} for the given registry. - * If the registry is {@link EnvironmentCapable}, e.g. is an {@code ApplicationContext}, - * the {@link Environment} will be inherited, otherwise a new - * {@link StandardEnvironment} will be created and used. - * @param registry the {@code BeanFactory} to load bean definitions into, - * in the form of a {@code BeanDefinitionRegistry} - * @see #AnnotatedBeanDefinitionReader(BeanDefinitionRegistry, Environment) - * @see #setEnvironment(Environment) - */ - public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) { - this(registry, getOrCreateEnvironment(registry)); - } - - /** - * Create a new {@code AnnotatedBeanDefinitionReader} for the given registry and using - * the given {@link Environment}. - * @param registry the {@code BeanFactory} to load bean definitions into, - * in the form of a {@code BeanDefinitionRegistry} - * @param environment the {@code Environment} to use when evaluating bean definition - * profiles. - * @since 3.1 - */ - public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) { - Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); - Assert.notNull(environment, "Environment must not be null"); - - this.registry = registry; - this.environment = environment; - - AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); - } - - /** - * Return the BeanDefinitionRegistry that this scanner operates on. - */ - public final BeanDefinitionRegistry getRegistry() { - return this.registry; - } - - /** - * Set the Environment to use when evaluating whether - * {@link Profile @Profile}-annotated component classes should be registered. - * <p>The default is a {@link StandardEnvironment}. - * @see #registerBean(Class, String, Class...) - */ - public void setEnvironment(Environment environment) { - this.environment = environment; - } - - /** - * Set the BeanNameGenerator to use for detected bean classes. - * <p>The default is a {@link AnnotationBeanNameGenerator}. - */ - public void setBeanNameGenerator(BeanNameGenerator beanNameGenerator) { - this.beanNameGenerator = (beanNameGenerator != null ? beanNameGenerator : new AnnotationBeanNameGenerator()); - } - - /** - * Set the ScopeMetadataResolver to use for detected bean classes. - * <p>The default is an {@link AnnotationScopeMetadataResolver}. - */ - public void setScopeMetadataResolver(ScopeMetadataResolver scopeMetadataResolver) { - this.scopeMetadataResolver = (scopeMetadataResolver != null ? scopeMetadataResolver - : new AnnotationScopeMetadataResolver()); - } - - public void register(Class<?>... annotatedClasses) { - for (Class<?> annotatedClass : annotatedClasses) { - registerBean(annotatedClass); - } - } - - public void registerBean(Class<?> annotatedClass) { - registerBean(annotatedClass, null, (Class<? extends Annotation>[]) null); - } - - public void registerBean(Class<?> annotatedClass, Class<? extends Annotation>... qualifiers) { - registerBean(annotatedClass, null, qualifiers); - } - - public void registerBean(Class<?> annotatedClass, String name, Class<? extends Annotation>... qualifiers) { - AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass); - AnnotationMetadata metadata = abd.getMetadata(); - - if (ProfileHelper.isProfileAnnotationPresent(metadata)) { - if (!this.environment.acceptsProfiles(ProfileHelper.getCandidateProfiles(metadata))) { - return; - } - } - ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd); - abd.setScope(scopeMetadata.getScopeName()); - String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry)); - AnnotationConfigUtils.processCommonDefinitionAnnotations(abd); - if (qualifiers != null) { - for (Class<? extends Annotation> qualifier : qualifiers) { - if (Primary.class.equals(qualifier)) { - abd.setPrimary(true); - } else if (Lazy.class.equals(qualifier)) { - abd.setLazyInit(true); - } else { - abd.addQualifier(new AutowireCandidateQualifier(qualifier)); - } - } - } - BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName); - definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); - BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry); - } - - - /** - * Get the Environment from the given registry if possible, otherwise return a new - * StandardEnvironment. - */ - private static Environment getOrCreateEnvironment(BeanDefinitionRegistry registry) { - Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); - if (registry instanceof EnvironmentCapable) { - return ((EnvironmentCapable) registry).getEnvironment(); - } - return new StandardEnvironment(); - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.context.annotation; + +import java.lang.annotation.Annotation; + +import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition; +import org.springframework.beans.factory.config.BeanDefinitionHolder; +import org.springframework.beans.factory.support.AutowireCandidateQualifier; +import org.springframework.beans.factory.support.BeanDefinitionReaderUtils; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.beans.factory.support.BeanNameGenerator; +import org.springframework.core.env.Environment; +import org.springframework.core.env.EnvironmentCapable; +import org.springframework.core.env.StandardEnvironment; +import org.springframework.core.type.AnnotationMetadata; +import org.springframework.util.Assert; + +/** + * Convenient adapter for programmatic registration of annotated bean classes. + * This is an alternative to {@link ClassPathBeanDefinitionScanner}, applying + * the same resolution of annotations but for explicitly registered classes only. + * + * @author Juergen Hoeller + * @author Chris Beams + * @author Sam Brannen + * @since 3.0 + * @see AnnotationConfigApplicationContext#register + */ +public class AnnotatedBeanDefinitionReader { + + private final BeanDefinitionRegistry registry; + + private Environment environment; + + private BeanNameGenerator beanNameGenerator = new AnnotationBeanNameGenerator(); + + private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver(); + + /** + * Create a new {@code AnnotatedBeanDefinitionReader} for the given registry. + * If the registry is {@link EnvironmentCapable}, e.g. is an {@code ApplicationContext}, + * the {@link Environment} will be inherited, otherwise a new + * {@link StandardEnvironment} will be created and used. + * @param registry the {@code BeanFactory} to load bean definitions into, + * in the form of a {@code BeanDefinitionRegistry} + * @see #AnnotatedBeanDefinitionReader(BeanDefinitionRegistry, Environment) + * @see #setEnvironment(Environment) + */ + public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) { + this(registry, getOrCreateEnvironment(registry)); + } + + /** + * Create a new {@code AnnotatedBeanDefinitionReader} for the given registry and using + * the given {@link Environment}. + * @param registry the {@code BeanFactory} to load bean definitions into, + * in the form of a {@code BeanDefinitionRegistry} + * @param environment the {@code Environment} to use when evaluating bean definition + * profiles. + * @since 3.1 + */ + public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) { + Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); + Assert.notNull(environment, "Environment must not be null"); + + this.registry = registry; + this.environment = environment; + + AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); + } + + /** + * Return the BeanDefinitionRegistry that this scanner operates on. + */ + public final BeanDefinitionRegistry getRegistry() { + return this.registry; + } + + /** + * Set the Environment to use when evaluating whether + * {@link Profile @Profile}-annotated component classes should be registered. + * <p>The default is a {@link StandardEnvironment}. + * @see #registerBean(Class, String, Class...) + */ + public void setEnvironment(Environment environment) { + this.environment = environment; + } + + /** + * Set the BeanNameGenerator to use for detected bean classes. + * <p>The default is a {@link AnnotationBeanNameGenerator}. + */ + public void setBeanNameGenerator(BeanNameGenerator beanNameGenerator) { + this.beanNameGenerator = (beanNameGenerator != null ? beanNameGenerator : new AnnotationBeanNameGenerator()); + } + + /** + * Set the ScopeMetadataResolver to use for detected bean classes. + * <p>The default is an {@link AnnotationScopeMetadataResolver}. + */ + public void setScopeMetadataResolver(ScopeMetadataResolver scopeMetadataResolver) { + this.scopeMetadataResolver = (scopeMetadataResolver != null ? scopeMetadataResolver + : new AnnotationScopeMetadataResolver()); + } + + public void register(Class<?>... annotatedClasses) { + for (Class<?> annotatedClass : annotatedClasses) { + registerBean(annotatedClass); + } + } + + public void registerBean(Class<?> annotatedClass) { + registerBean(annotatedClass, null, (Class<? extends Annotation>[]) null); + } + + public void registerBean(Class<?> annotatedClass, Class<? extends Annotation>... qualifiers) { + registerBean(annotatedClass, null, qualifiers); + } + + public void registerBean(Class<?> annotatedClass, String name, Class<? extends Annotation>... qualifiers) { + AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass); + AnnotationMetadata metadata = abd.getMetadata(); + + if (ProfileHelper.isProfileAnnotationPresent(metadata)) { + if (!this.environment.acceptsProfiles(ProfileHelper.getCandidateProfiles(metadata))) { + return; + } + } + ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd); + abd.setScope(scopeMetadata.getScopeName()); + String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry)); + AnnotationConfigUtils.processCommonDefinitionAnnotations(abd); + if (qualifiers != null) { + for (Class<? extends Annotation> qualifier : qualifiers) { + if (Primary.class.equals(qualifier)) { + abd.setPrimary(true); + } else if (Lazy.class.equals(qualifier)) { + abd.setLazyInit(true); + } else { + abd.addQualifier(new AutowireCandidateQualifier(qualifier)); + } + } + } + BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName); + definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); + BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry); + } + + + /** + * Get the Environment from the given registry if possible, otherwise return a new + * StandardEnvironment. + */ + private static Environment getOrCreateEnvironment(BeanDefinitionRegistry registry) { + Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); + if (registry instanceof EnvironmentCapable) { + return ((EnvironmentCapable) registry).getEnvironment(); + } + return new StandardEnvironment(); + } + +} diff --git a/org.springframework.context/src/main/java/org/springframework/context/annotation/DependsOn.java b/org.springframework.context/src/main/java/org/springframework/context/annotation/DependsOn.java index 1fee1a0f9fa..59bd215857c 100644 --- a/org.springframework.context/src/main/java/org/springframework/context/annotation/DependsOn.java +++ b/org.springframework.context/src/main/java/org/springframework/context/annotation/DependsOn.java @@ -1,54 +1,54 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.context.annotation; - -import java.lang.annotation.Target; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Inherited; -import java.lang.annotation.Documented; - -/** - * Beans on which the current bean depends. Any beans specified are guaranteed to be - * created by the container before this bean. Used infrequently in cases where a bean - * does not explicitly depend on another through properties or constructor arguments, - * but rather depends on the side effects of another bean's initialization. - * <p>Note: This attribute will not be inherited by child bean definitions, - * hence it needs to be specified per concrete bean definition. - * - * <p>May be used on any class directly or indirectly annotated with - * {@link org.springframework.stereotype.Component} or on methods annotated - * with {@link Bean}. - * - * <p>Using {@link DependsOn} at the class level has no effect unless component-scanning - * is being used. If a {@link DependsOn}-annotated class is declared via XML, - * {@link DependsOn} annotation metadata is ignored, and - * {@code <bean depends-on="..."/>} is respected instead. - * - * @author Juergen Hoeller - * @since 3.0 - */ -@Target({ElementType.TYPE, ElementType.METHOD}) -@Retention(RetentionPolicy.RUNTIME) -@Inherited -@Documented -public @interface DependsOn { - - String[] value() default {}; - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.context.annotation; + +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Inherited; +import java.lang.annotation.Documented; + +/** + * Beans on which the current bean depends. Any beans specified are guaranteed to be + * created by the container before this bean. Used infrequently in cases where a bean + * does not explicitly depend on another through properties or constructor arguments, + * but rather depends on the side effects of another bean's initialization. + * <p>Note: This attribute will not be inherited by child bean definitions, + * hence it needs to be specified per concrete bean definition. + * + * <p>May be used on any class directly or indirectly annotated with + * {@link org.springframework.stereotype.Component} or on methods annotated + * with {@link Bean}. + * + * <p>Using {@link DependsOn} at the class level has no effect unless component-scanning + * is being used. If a {@link DependsOn}-annotated class is declared via XML, + * {@link DependsOn} annotation metadata is ignored, and + * {@code <bean depends-on="..."/>} is respected instead. + * + * @author Juergen Hoeller + * @since 3.0 + */ +@Target({ElementType.TYPE, ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Inherited +@Documented +public @interface DependsOn { + + String[] value() default {}; + +} diff --git a/org.springframework.context/src/main/java/org/springframework/context/annotation/Jsr330ScopeMetadataResolver.java b/org.springframework.context/src/main/java/org/springframework/context/annotation/Jsr330ScopeMetadataResolver.java index 61e79114b96..8549d97f8e9 100644 --- a/org.springframework.context/src/main/java/org/springframework/context/annotation/Jsr330ScopeMetadataResolver.java +++ b/org.springframework.context/src/main/java/org/springframework/context/annotation/Jsr330ScopeMetadataResolver.java @@ -1,111 +1,111 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.context.annotation; - -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition; -import org.springframework.beans.factory.config.BeanDefinition; - -/** - * Simple {@link ScopeMetadataResolver} implementation that follows JSR-330 scoping rules: - * defaulting to prototype scope unless {@link javax.inject.Singleton} is present. - * - * <p>This scope resolver can be used with {@link ClassPathBeanDefinitionScanner} and - * {@link AnnotatedBeanDefinitionReader} for standard JSR-330 compliance. However, - * in practice, you will typically use Spring's rich default scoping instead - or extend - * this resolver with custom scoping annotations that point to extended Spring scopes. - * - * @author Juergen Hoeller - * @since 3.0 - * @see #registerScope - * @see #resolveScopeName - * @see ClassPathBeanDefinitionScanner#setScopeMetadataResolver - * @see AnnotatedBeanDefinitionReader#setScopeMetadataResolver - */ -public class Jsr330ScopeMetadataResolver implements ScopeMetadataResolver { - - private final Map<String, String> scopeMap = new HashMap<String, String>(); - - - public Jsr330ScopeMetadataResolver() { - registerScope("javax.inject.Singleton", BeanDefinition.SCOPE_SINGLETON); - } - - - /** - * Register an extended JSR-330 scope annotation, mapping it onto a - * specific Spring scope by name. - * @param annotationType the JSR-330 annotation type as a Class - * @param scopeName the Spring scope name - */ - public final void registerScope(Class annotationType, String scopeName) { - this.scopeMap.put(annotationType.getName(), scopeName); - } - - /** - * Register an extended JSR-330 scope annotation, mapping it onto a - * specific Spring scope by name. - * @param annotationType the JSR-330 annotation type by name - * @param scopeName the Spring scope name - */ - public final void registerScope(String annotationType, String scopeName) { - this.scopeMap.put(annotationType, scopeName); - } - - /** - * Resolve the given annotation type into a named Spring scope. - * <p>The default implementation simply checks against registered scopes. - * Can be overridden for custom mapping rules, e.g. naming conventions. - * @param annotationType the JSR-330 annotation type - * @return the Spring scope name - */ - protected String resolveScopeName(String annotationType) { - return this.scopeMap.get(annotationType); - } - - - public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) { - ScopeMetadata metadata = new ScopeMetadata(); - metadata.setScopeName(BeanDefinition.SCOPE_PROTOTYPE); - if (definition instanceof AnnotatedBeanDefinition) { - AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition; - Set<String> annTypes = annDef.getMetadata().getAnnotationTypes(); - String found = null; - for (String annType : annTypes) { - Set<String> metaAnns = annDef.getMetadata().getMetaAnnotationTypes(annType); - if (metaAnns.contains("javax.inject.Scope")) { - if (found != null) { - throw new IllegalStateException("Found ambiguous scope annotations on bean class [" + - definition.getBeanClassName() + "]: " + found + ", " + annType); - } - found = annType; - String scopeName = resolveScopeName(annType); - if (scopeName == null) { - throw new IllegalStateException( - "Unsupported scope annotation - not mapped onto Spring scope name: " + annType); - } - metadata.setScopeName(scopeName); - } - } - } - return metadata; - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.context.annotation; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition; +import org.springframework.beans.factory.config.BeanDefinition; + +/** + * Simple {@link ScopeMetadataResolver} implementation that follows JSR-330 scoping rules: + * defaulting to prototype scope unless {@link javax.inject.Singleton} is present. + * + * <p>This scope resolver can be used with {@link ClassPathBeanDefinitionScanner} and + * {@link AnnotatedBeanDefinitionReader} for standard JSR-330 compliance. However, + * in practice, you will typically use Spring's rich default scoping instead - or extend + * this resolver with custom scoping annotations that point to extended Spring scopes. + * + * @author Juergen Hoeller + * @since 3.0 + * @see #registerScope + * @see #resolveScopeName + * @see ClassPathBeanDefinitionScanner#setScopeMetadataResolver + * @see AnnotatedBeanDefinitionReader#setScopeMetadataResolver + */ +public class Jsr330ScopeMetadataResolver implements ScopeMetadataResolver { + + private final Map<String, String> scopeMap = new HashMap<String, String>(); + + + public Jsr330ScopeMetadataResolver() { + registerScope("javax.inject.Singleton", BeanDefinition.SCOPE_SINGLETON); + } + + + /** + * Register an extended JSR-330 scope annotation, mapping it onto a + * specific Spring scope by name. + * @param annotationType the JSR-330 annotation type as a Class + * @param scopeName the Spring scope name + */ + public final void registerScope(Class annotationType, String scopeName) { + this.scopeMap.put(annotationType.getName(), scopeName); + } + + /** + * Register an extended JSR-330 scope annotation, mapping it onto a + * specific Spring scope by name. + * @param annotationType the JSR-330 annotation type by name + * @param scopeName the Spring scope name + */ + public final void registerScope(String annotationType, String scopeName) { + this.scopeMap.put(annotationType, scopeName); + } + + /** + * Resolve the given annotation type into a named Spring scope. + * <p>The default implementation simply checks against registered scopes. + * Can be overridden for custom mapping rules, e.g. naming conventions. + * @param annotationType the JSR-330 annotation type + * @return the Spring scope name + */ + protected String resolveScopeName(String annotationType) { + return this.scopeMap.get(annotationType); + } + + + public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) { + ScopeMetadata metadata = new ScopeMetadata(); + metadata.setScopeName(BeanDefinition.SCOPE_PROTOTYPE); + if (definition instanceof AnnotatedBeanDefinition) { + AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition; + Set<String> annTypes = annDef.getMetadata().getAnnotationTypes(); + String found = null; + for (String annType : annTypes) { + Set<String> metaAnns = annDef.getMetadata().getMetaAnnotationTypes(annType); + if (metaAnns.contains("javax.inject.Scope")) { + if (found != null) { + throw new IllegalStateException("Found ambiguous scope annotations on bean class [" + + definition.getBeanClassName() + "]: " + found + ", " + annType); + } + found = annType; + String scopeName = resolveScopeName(annType); + if (scopeName == null) { + throw new IllegalStateException( + "Unsupported scope annotation - not mapped onto Spring scope name: " + annType); + } + metadata.setScopeName(scopeName); + } + } + } + return metadata; + } + +} diff --git a/org.springframework.context/src/main/java/org/springframework/context/annotation/ScopedProxyCreator.java b/org.springframework.context/src/main/java/org/springframework/context/annotation/ScopedProxyCreator.java index 5ede63ea353..371c8b66741 100644 --- a/org.springframework.context/src/main/java/org/springframework/context/annotation/ScopedProxyCreator.java +++ b/org.springframework.context/src/main/java/org/springframework/context/annotation/ScopedProxyCreator.java @@ -1,43 +1,43 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.context.annotation; - -import org.springframework.aop.scope.ScopedProxyUtils; -import org.springframework.beans.factory.config.BeanDefinitionHolder; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; - -/** - * Delegate factory class used to just introduce an AOP framework dependency - * when actually creating a scoped proxy. - * - * @author Juergen Hoeller - * @since 3.0 - * @see org.springframework.aop.scope.ScopedProxyUtils#createScopedProxy - */ -class ScopedProxyCreator { - - public static BeanDefinitionHolder createScopedProxy( - BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry, boolean proxyTargetClass) { - - return ScopedProxyUtils.createScopedProxy(definitionHolder, registry, proxyTargetClass); - } - - public static String getTargetBeanName(String originalBeanName) { - return ScopedProxyUtils.getTargetBeanName(originalBeanName); - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.context.annotation; + +import org.springframework.aop.scope.ScopedProxyUtils; +import org.springframework.beans.factory.config.BeanDefinitionHolder; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; + +/** + * Delegate factory class used to just introduce an AOP framework dependency + * when actually creating a scoped proxy. + * + * @author Juergen Hoeller + * @since 3.0 + * @see org.springframework.aop.scope.ScopedProxyUtils#createScopedProxy + */ +class ScopedProxyCreator { + + public static BeanDefinitionHolder createScopedProxy( + BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry, boolean proxyTargetClass) { + + return ScopedProxyUtils.createScopedProxy(definitionHolder, registry, proxyTargetClass); + } + + public static String getTargetBeanName(String originalBeanName) { + return ScopedProxyUtils.getTargetBeanName(originalBeanName); + } + +} diff --git a/org.springframework.context/src/main/java/org/springframework/context/event/GenericApplicationListenerAdapter.java b/org.springframework.context/src/main/java/org/springframework/context/event/GenericApplicationListenerAdapter.java index 087dcf46fa8..5866212e871 100644 --- a/org.springframework.context/src/main/java/org/springframework/context/event/GenericApplicationListenerAdapter.java +++ b/org.springframework.context/src/main/java/org/springframework/context/event/GenericApplicationListenerAdapter.java @@ -1,73 +1,73 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.context.event; - -import org.springframework.aop.support.AopUtils; -import org.springframework.context.ApplicationEvent; -import org.springframework.context.ApplicationListener; -import org.springframework.core.GenericTypeResolver; -import org.springframework.core.Ordered; -import org.springframework.util.Assert; - -/** - * {@link SmartApplicationListener} adapter that determines supported event types - * through introspecting the generically declared type of the target listener. - * - * @author Juergen Hoeller - * @since 3.0 - * @see org.springframework.context.ApplicationListener#onApplicationEvent - */ -public class GenericApplicationListenerAdapter implements SmartApplicationListener { - - private final ApplicationListener delegate; - - - /** - * Create a new GenericApplicationListener for the given delegate. - * @param delegate the delegate listener to be invoked - */ - public GenericApplicationListenerAdapter(ApplicationListener delegate) { - Assert.notNull(delegate, "Delegate listener must not be null"); - this.delegate = delegate; - } - - - @SuppressWarnings("unchecked") - public void onApplicationEvent(ApplicationEvent event) { - this.delegate.onApplicationEvent(event); - } - - public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) { - Class typeArg = GenericTypeResolver.resolveTypeArgument(this.delegate.getClass(), ApplicationListener.class); - if (typeArg == null || typeArg.equals(ApplicationEvent.class)) { - Class targetClass = AopUtils.getTargetClass(this.delegate); - if (targetClass != this.delegate.getClass()) { - typeArg = GenericTypeResolver.resolveTypeArgument(targetClass, ApplicationListener.class); - } - } - return (typeArg == null || typeArg.isAssignableFrom(eventType)); - } - - public boolean supportsSourceType(Class<?> sourceType) { - return true; - } - - public int getOrder() { - return (this.delegate instanceof Ordered ? ((Ordered) this.delegate).getOrder() : Ordered.LOWEST_PRECEDENCE); - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.context.event; + +import org.springframework.aop.support.AopUtils; +import org.springframework.context.ApplicationEvent; +import org.springframework.context.ApplicationListener; +import org.springframework.core.GenericTypeResolver; +import org.springframework.core.Ordered; +import org.springframework.util.Assert; + +/** + * {@link SmartApplicationListener} adapter that determines supported event types + * through introspecting the generically declared type of the target listener. + * + * @author Juergen Hoeller + * @since 3.0 + * @see org.springframework.context.ApplicationListener#onApplicationEvent + */ +public class GenericApplicationListenerAdapter implements SmartApplicationListener { + + private final ApplicationListener delegate; + + + /** + * Create a new GenericApplicationListener for the given delegate. + * @param delegate the delegate listener to be invoked + */ + public GenericApplicationListenerAdapter(ApplicationListener delegate) { + Assert.notNull(delegate, "Delegate listener must not be null"); + this.delegate = delegate; + } + + + @SuppressWarnings("unchecked") + public void onApplicationEvent(ApplicationEvent event) { + this.delegate.onApplicationEvent(event); + } + + public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) { + Class typeArg = GenericTypeResolver.resolveTypeArgument(this.delegate.getClass(), ApplicationListener.class); + if (typeArg == null || typeArg.equals(ApplicationEvent.class)) { + Class targetClass = AopUtils.getTargetClass(this.delegate); + if (targetClass != this.delegate.getClass()) { + typeArg = GenericTypeResolver.resolveTypeArgument(targetClass, ApplicationListener.class); + } + } + return (typeArg == null || typeArg.isAssignableFrom(eventType)); + } + + public boolean supportsSourceType(Class<?> sourceType) { + return true; + } + + public int getOrder() { + return (this.delegate instanceof Ordered ? ((Ordered) this.delegate).getOrder() : Ordered.LOWEST_PRECEDENCE); + } + +} diff --git a/org.springframework.context/src/main/java/org/springframework/context/event/SmartApplicationListener.java b/org.springframework.context/src/main/java/org/springframework/context/event/SmartApplicationListener.java index 1dcd739e901..9fe22adaf1e 100644 --- a/org.springframework.context/src/main/java/org/springframework/context/event/SmartApplicationListener.java +++ b/org.springframework.context/src/main/java/org/springframework/context/event/SmartApplicationListener.java @@ -1,42 +1,42 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.context.event; - -import org.springframework.context.ApplicationEvent; -import org.springframework.context.ApplicationListener; -import org.springframework.core.Ordered; - -/** - * Extended variant of the standard {@link ApplicationListener} interface, - * exposing further metadata such as the supported event type. - * - * @author Juergen Hoeller - * @since 3.0 - */ -public interface SmartApplicationListener extends ApplicationListener<ApplicationEvent>, Ordered { - - /** - * Determine whether this listener actually supports the given event type. - */ - boolean supportsEventType(Class<? extends ApplicationEvent> eventType); - - /** - * Determine whether this listener actually supports the given source type. - */ - boolean supportsSourceType(Class<?> sourceType); - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.context.event; + +import org.springframework.context.ApplicationEvent; +import org.springframework.context.ApplicationListener; +import org.springframework.core.Ordered; + +/** + * Extended variant of the standard {@link ApplicationListener} interface, + * exposing further metadata such as the supported event type. + * + * @author Juergen Hoeller + * @since 3.0 + */ +public interface SmartApplicationListener extends ApplicationListener<ApplicationEvent>, Ordered { + + /** + * Determine whether this listener actually supports the given event type. + */ + boolean supportsEventType(Class<? extends ApplicationEvent> eventType); + + /** + * Determine whether this listener actually supports the given source type. + */ + boolean supportsSourceType(Class<?> sourceType); + +} diff --git a/org.springframework.context/src/main/java/org/springframework/context/expression/BeanExpressionContextAccessor.java b/org.springframework.context/src/main/java/org/springframework/context/expression/BeanExpressionContextAccessor.java index 89bc6b6a437..e81c929e811 100644 --- a/org.springframework.context/src/main/java/org/springframework/context/expression/BeanExpressionContextAccessor.java +++ b/org.springframework.context/src/main/java/org/springframework/context/expression/BeanExpressionContextAccessor.java @@ -1,55 +1,55 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.context.expression; - -import org.springframework.beans.factory.config.BeanExpressionContext; -import org.springframework.expression.AccessException; -import org.springframework.expression.EvaluationContext; -import org.springframework.expression.PropertyAccessor; -import org.springframework.expression.TypedValue; - -/** - * EL property accessor that knows how to traverse the beans and contextual objects - * of a Spring {@link org.springframework.beans.factory.config.BeanExpressionContext}. - * - * @author Juergen Hoeller - * @author Andy Clement - * @since 3.0 - */ -public class BeanExpressionContextAccessor implements PropertyAccessor { - - public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException { - return ((BeanExpressionContext) target).containsObject(name); - } - - public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException { - return new TypedValue(((BeanExpressionContext) target).getObject(name)); - } - - public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException { - return false; - } - - public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException { - throw new AccessException("Beans in a BeanFactory are read-only"); - } - - public Class[] getSpecificTargetClasses() { - return new Class[] {BeanExpressionContext.class}; - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.context.expression; + +import org.springframework.beans.factory.config.BeanExpressionContext; +import org.springframework.expression.AccessException; +import org.springframework.expression.EvaluationContext; +import org.springframework.expression.PropertyAccessor; +import org.springframework.expression.TypedValue; + +/** + * EL property accessor that knows how to traverse the beans and contextual objects + * of a Spring {@link org.springframework.beans.factory.config.BeanExpressionContext}. + * + * @author Juergen Hoeller + * @author Andy Clement + * @since 3.0 + */ +public class BeanExpressionContextAccessor implements PropertyAccessor { + + public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException { + return ((BeanExpressionContext) target).containsObject(name); + } + + public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException { + return new TypedValue(((BeanExpressionContext) target).getObject(name)); + } + + public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException { + return false; + } + + public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException { + throw new AccessException("Beans in a BeanFactory are read-only"); + } + + public Class[] getSpecificTargetClasses() { + return new Class[] {BeanExpressionContext.class}; + } + +} diff --git a/org.springframework.context/src/main/java/org/springframework/context/expression/BeanFactoryAccessor.java b/org.springframework.context/src/main/java/org/springframework/context/expression/BeanFactoryAccessor.java index 66157a604bc..486ded925fd 100644 --- a/org.springframework.context/src/main/java/org/springframework/context/expression/BeanFactoryAccessor.java +++ b/org.springframework.context/src/main/java/org/springframework/context/expression/BeanFactoryAccessor.java @@ -1,55 +1,55 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.context.expression; - -import org.springframework.beans.factory.BeanFactory; -import org.springframework.expression.AccessException; -import org.springframework.expression.EvaluationContext; -import org.springframework.expression.PropertyAccessor; -import org.springframework.expression.TypedValue; - -/** - * EL property accessor that knows how to traverse the beans of a - * Spring {@link org.springframework.beans.factory.BeanFactory}. - * - * @author Juergen Hoeller - * @author Andy Clement - * @since 3.0 - */ -public class BeanFactoryAccessor implements PropertyAccessor { - - public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException { - return (((BeanFactory) target).containsBean(name)); - } - - public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException { - return new TypedValue(((BeanFactory) target).getBean(name)); - } - - public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException { - return false; - } - - public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException { - throw new AccessException("Beans in a BeanFactory are read-only"); - } - - public Class[] getSpecificTargetClasses() { - return new Class[] {BeanFactory.class}; - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.context.expression; + +import org.springframework.beans.factory.BeanFactory; +import org.springframework.expression.AccessException; +import org.springframework.expression.EvaluationContext; +import org.springframework.expression.PropertyAccessor; +import org.springframework.expression.TypedValue; + +/** + * EL property accessor that knows how to traverse the beans of a + * Spring {@link org.springframework.beans.factory.BeanFactory}. + * + * @author Juergen Hoeller + * @author Andy Clement + * @since 3.0 + */ +public class BeanFactoryAccessor implements PropertyAccessor { + + public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException { + return (((BeanFactory) target).containsBean(name)); + } + + public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException { + return new TypedValue(((BeanFactory) target).getBean(name)); + } + + public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException { + return false; + } + + public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException { + throw new AccessException("Beans in a BeanFactory are read-only"); + } + + public Class[] getSpecificTargetClasses() { + return new Class[] {BeanFactory.class}; + } + +} diff --git a/org.springframework.context/src/main/java/org/springframework/context/expression/BeanFactoryResolver.java b/org.springframework.context/src/main/java/org/springframework/context/expression/BeanFactoryResolver.java index 894a196f514..ff4aaaa78da 100644 --- a/org.springframework.context/src/main/java/org/springframework/context/expression/BeanFactoryResolver.java +++ b/org.springframework.context/src/main/java/org/springframework/context/expression/BeanFactoryResolver.java @@ -1,51 +1,51 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.context.expression; - -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.expression.AccessException; -import org.springframework.expression.BeanResolver; -import org.springframework.expression.EvaluationContext; -import org.springframework.util.Assert; - -/** - * EL bean resolver that operates against a Spring - * {@link org.springframework.beans.factory.BeanFactory}. - * - * @author Juergen Hoeller - * @since 3.0.4 - */ -public class BeanFactoryResolver implements BeanResolver { - - private final BeanFactory beanFactory; - - public BeanFactoryResolver(BeanFactory beanFactory) { - Assert.notNull(beanFactory, "BeanFactory must not be null"); - this.beanFactory = beanFactory; - } - - public Object resolve(EvaluationContext context, String beanName) throws AccessException { - try { - return this.beanFactory.getBean(beanName); - } - catch (BeansException ex) { - throw new AccessException("Could not resolve bean reference against BeanFactory", ex); - } - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.context.expression; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.expression.AccessException; +import org.springframework.expression.BeanResolver; +import org.springframework.expression.EvaluationContext; +import org.springframework.util.Assert; + +/** + * EL bean resolver that operates against a Spring + * {@link org.springframework.beans.factory.BeanFactory}. + * + * @author Juergen Hoeller + * @since 3.0.4 + */ +public class BeanFactoryResolver implements BeanResolver { + + private final BeanFactory beanFactory; + + public BeanFactoryResolver(BeanFactory beanFactory) { + Assert.notNull(beanFactory, "BeanFactory must not be null"); + this.beanFactory = beanFactory; + } + + public Object resolve(EvaluationContext context, String beanName) throws AccessException { + try { + return this.beanFactory.getBean(beanName); + } + catch (BeansException ex) { + throw new AccessException("Could not resolve bean reference against BeanFactory", ex); + } + } + +} diff --git a/org.springframework.context/src/main/java/org/springframework/context/expression/MapAccessor.java b/org.springframework.context/src/main/java/org/springframework/context/expression/MapAccessor.java index bb523849b4a..53ed9ce9114 100644 --- a/org.springframework.context/src/main/java/org/springframework/context/expression/MapAccessor.java +++ b/org.springframework.context/src/main/java/org/springframework/context/expression/MapAccessor.java @@ -1,84 +1,84 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.context.expression; - -import java.util.Map; - -import org.springframework.expression.AccessException; -import org.springframework.expression.EvaluationContext; -import org.springframework.expression.PropertyAccessor; -import org.springframework.expression.TypedValue; - -/** - * EL property accessor that knows how to traverse the keys - * of a standard {@link java.util.Map}. - * - * @author Juergen Hoeller - * @author Andy Clement - * @since 3.0 - */ -public class MapAccessor implements PropertyAccessor { - - public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException { - Map map = (Map) target; - return map.containsKey(name); - } - - public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException { - Map map = (Map) target; - Object value = map.get(name); - if (value == null && !map.containsKey(name)) { - throw new MapAccessException(name); - } - return new TypedValue(value); - } - - public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException { - return true; - } - - @SuppressWarnings("unchecked") - public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException { - Map map = (Map) target; - map.put(name, newValue); - } - - public Class[] getSpecificTargetClasses() { - return new Class[] {Map.class}; - } - - - /** - * Exception thrown from <code>read</code> in order to reset a cached - * PropertyAccessor, allowing other accessors to have a try. - */ - private static class MapAccessException extends AccessException { - - private final String key; - - public MapAccessException(String key) { - super(null); - this.key = key; - } - - @Override - public String getMessage() { - return "Map does not contain a value for key '" + this.key + "'"; - } - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.context.expression; + +import java.util.Map; + +import org.springframework.expression.AccessException; +import org.springframework.expression.EvaluationContext; +import org.springframework.expression.PropertyAccessor; +import org.springframework.expression.TypedValue; + +/** + * EL property accessor that knows how to traverse the keys + * of a standard {@link java.util.Map}. + * + * @author Juergen Hoeller + * @author Andy Clement + * @since 3.0 + */ +public class MapAccessor implements PropertyAccessor { + + public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException { + Map map = (Map) target; + return map.containsKey(name); + } + + public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException { + Map map = (Map) target; + Object value = map.get(name); + if (value == null && !map.containsKey(name)) { + throw new MapAccessException(name); + } + return new TypedValue(value); + } + + public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException { + return true; + } + + @SuppressWarnings("unchecked") + public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException { + Map map = (Map) target; + map.put(name, newValue); + } + + public Class[] getSpecificTargetClasses() { + return new Class[] {Map.class}; + } + + + /** + * Exception thrown from <code>read</code> in order to reset a cached + * PropertyAccessor, allowing other accessors to have a try. + */ + private static class MapAccessException extends AccessException { + + private final String key; + + public MapAccessException(String key) { + super(null); + this.key = key; + } + + @Override + public String getMessage() { + return "Map does not contain a value for key '" + this.key + "'"; + } + } + +} diff --git a/org.springframework.context/src/main/java/org/springframework/context/expression/StandardBeanExpressionResolver.java b/org.springframework.context/src/main/java/org/springframework/context/expression/StandardBeanExpressionResolver.java index 9fb19609528..80b546f2e67 100644 --- a/org.springframework.context/src/main/java/org/springframework/context/expression/StandardBeanExpressionResolver.java +++ b/org.springframework.context/src/main/java/org/springframework/context/expression/StandardBeanExpressionResolver.java @@ -1,153 +1,153 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.context.expression; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanExpressionException; -import org.springframework.beans.factory.config.BeanExpressionContext; -import org.springframework.beans.factory.config.BeanExpressionResolver; -import org.springframework.core.convert.ConversionService; -import org.springframework.expression.Expression; -import org.springframework.expression.ExpressionParser; -import org.springframework.expression.ParserContext; -import org.springframework.expression.spel.standard.SpelExpressionParser; -import org.springframework.expression.spel.support.StandardEvaluationContext; -import org.springframework.expression.spel.support.StandardTypeConverter; -import org.springframework.expression.spel.support.StandardTypeLocator; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; - -/** - * Standard implementation of the - * {@link org.springframework.beans.factory.config.BeanExpressionResolver} - * interface, parsing and evaluating Spring EL using Spring's expression module. - * - * @author Juergen Hoeller - * @since 3.0 - * @see org.springframework.expression.ExpressionParser - * @see org.springframework.expression.spel.standard.SpelExpressionParser - * @see org.springframework.expression.spel.support.StandardEvaluationContext - */ -public class StandardBeanExpressionResolver implements BeanExpressionResolver { - - /** Default expression prefix: "#{" */ - public static final String DEFAULT_EXPRESSION_PREFIX = "#{"; - - /** Default expression suffix: "}" */ - public static final String DEFAULT_EXPRESSION_SUFFIX = "}"; - - - private String expressionPrefix = DEFAULT_EXPRESSION_PREFIX; - - private String expressionSuffix = DEFAULT_EXPRESSION_SUFFIX; - - private ExpressionParser expressionParser = new SpelExpressionParser(); - - private final Map<String, Expression> expressionCache = new ConcurrentHashMap<String, Expression>(); - - private final Map<BeanExpressionContext, StandardEvaluationContext> evaluationCache = - new ConcurrentHashMap<BeanExpressionContext, StandardEvaluationContext>(); - - private final ParserContext beanExpressionParserContext = new ParserContext() { - public boolean isTemplate() { - return true; - } - public String getExpressionPrefix() { - return expressionPrefix; - } - public String getExpressionSuffix() { - return expressionSuffix; - } - }; - - - /** - * Set the prefix that an expression string starts with. - * The default is "#{". - * @see #DEFAULT_EXPRESSION_PREFIX - */ - public void setExpressionPrefix(String expressionPrefix) { - Assert.hasText(expressionPrefix, "Expression prefix must not be empty"); - this.expressionPrefix = expressionPrefix; - } - - /** - * Set the suffix that an expression string ends with. - * The default is "}". - * @see #DEFAULT_EXPRESSION_SUFFIX - */ - public void setExpressionSuffix(String expressionSuffix) { - Assert.hasText(expressionSuffix, "Expression suffix must not be empty"); - this.expressionSuffix = expressionSuffix; - } - - /** - * Specify the EL parser to use for expression parsing. - * <p>Default is a {@link org.springframework.expression.spel.standard.SpelExpressionParser}, - * compatible with standard Unified EL style expression syntax. - */ - public void setExpressionParser(ExpressionParser expressionParser) { - Assert.notNull(expressionParser, "ExpressionParser must not be null"); - this.expressionParser = expressionParser; - } - - - public Object evaluate(String value, BeanExpressionContext evalContext) throws BeansException { - if (!StringUtils.hasLength(value)) { - return value; - } - try { - Expression expr = this.expressionCache.get(value); - if (expr == null) { - expr = this.expressionParser.parseExpression(value, this.beanExpressionParserContext); - this.expressionCache.put(value, expr); - } - StandardEvaluationContext sec = this.evaluationCache.get(evalContext); - if (sec == null) { - sec = new StandardEvaluationContext(); - sec.setRootObject(evalContext); - sec.addPropertyAccessor(new BeanExpressionContextAccessor()); - sec.addPropertyAccessor(new BeanFactoryAccessor()); - sec.addPropertyAccessor(new MapAccessor()); - sec.addPropertyAccessor(new EnvironmentAccessor()); - sec.setBeanResolver(new BeanFactoryResolver(evalContext.getBeanFactory())); - sec.setTypeLocator(new StandardTypeLocator(evalContext.getBeanFactory().getBeanClassLoader())); - ConversionService conversionService = evalContext.getBeanFactory().getConversionService(); - if (conversionService != null) { - sec.setTypeConverter(new StandardTypeConverter(conversionService)); - } - customizeEvaluationContext(sec); - this.evaluationCache.put(evalContext, sec); - } - return expr.getValue(sec); - } - catch (Exception ex) { - throw new BeanExpressionException("Expression parsing failed", ex); - } - } - - /** - * Template method for customizing the expression evaluation context. - * <p>The default implementation is empty. - */ - protected void customizeEvaluationContext(StandardEvaluationContext evalContext) { - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.context.expression; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanExpressionException; +import org.springframework.beans.factory.config.BeanExpressionContext; +import org.springframework.beans.factory.config.BeanExpressionResolver; +import org.springframework.core.convert.ConversionService; +import org.springframework.expression.Expression; +import org.springframework.expression.ExpressionParser; +import org.springframework.expression.ParserContext; +import org.springframework.expression.spel.standard.SpelExpressionParser; +import org.springframework.expression.spel.support.StandardEvaluationContext; +import org.springframework.expression.spel.support.StandardTypeConverter; +import org.springframework.expression.spel.support.StandardTypeLocator; +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; + +/** + * Standard implementation of the + * {@link org.springframework.beans.factory.config.BeanExpressionResolver} + * interface, parsing and evaluating Spring EL using Spring's expression module. + * + * @author Juergen Hoeller + * @since 3.0 + * @see org.springframework.expression.ExpressionParser + * @see org.springframework.expression.spel.standard.SpelExpressionParser + * @see org.springframework.expression.spel.support.StandardEvaluationContext + */ +public class StandardBeanExpressionResolver implements BeanExpressionResolver { + + /** Default expression prefix: "#{" */ + public static final String DEFAULT_EXPRESSION_PREFIX = "#{"; + + /** Default expression suffix: "}" */ + public static final String DEFAULT_EXPRESSION_SUFFIX = "}"; + + + private String expressionPrefix = DEFAULT_EXPRESSION_PREFIX; + + private String expressionSuffix = DEFAULT_EXPRESSION_SUFFIX; + + private ExpressionParser expressionParser = new SpelExpressionParser(); + + private final Map<String, Expression> expressionCache = new ConcurrentHashMap<String, Expression>(); + + private final Map<BeanExpressionContext, StandardEvaluationContext> evaluationCache = + new ConcurrentHashMap<BeanExpressionContext, StandardEvaluationContext>(); + + private final ParserContext beanExpressionParserContext = new ParserContext() { + public boolean isTemplate() { + return true; + } + public String getExpressionPrefix() { + return expressionPrefix; + } + public String getExpressionSuffix() { + return expressionSuffix; + } + }; + + + /** + * Set the prefix that an expression string starts with. + * The default is "#{". + * @see #DEFAULT_EXPRESSION_PREFIX + */ + public void setExpressionPrefix(String expressionPrefix) { + Assert.hasText(expressionPrefix, "Expression prefix must not be empty"); + this.expressionPrefix = expressionPrefix; + } + + /** + * Set the suffix that an expression string ends with. + * The default is "}". + * @see #DEFAULT_EXPRESSION_SUFFIX + */ + public void setExpressionSuffix(String expressionSuffix) { + Assert.hasText(expressionSuffix, "Expression suffix must not be empty"); + this.expressionSuffix = expressionSuffix; + } + + /** + * Specify the EL parser to use for expression parsing. + * <p>Default is a {@link org.springframework.expression.spel.standard.SpelExpressionParser}, + * compatible with standard Unified EL style expression syntax. + */ + public void setExpressionParser(ExpressionParser expressionParser) { + Assert.notNull(expressionParser, "ExpressionParser must not be null"); + this.expressionParser = expressionParser; + } + + + public Object evaluate(String value, BeanExpressionContext evalContext) throws BeansException { + if (!StringUtils.hasLength(value)) { + return value; + } + try { + Expression expr = this.expressionCache.get(value); + if (expr == null) { + expr = this.expressionParser.parseExpression(value, this.beanExpressionParserContext); + this.expressionCache.put(value, expr); + } + StandardEvaluationContext sec = this.evaluationCache.get(evalContext); + if (sec == null) { + sec = new StandardEvaluationContext(); + sec.setRootObject(evalContext); + sec.addPropertyAccessor(new BeanExpressionContextAccessor()); + sec.addPropertyAccessor(new BeanFactoryAccessor()); + sec.addPropertyAccessor(new MapAccessor()); + sec.addPropertyAccessor(new EnvironmentAccessor()); + sec.setBeanResolver(new BeanFactoryResolver(evalContext.getBeanFactory())); + sec.setTypeLocator(new StandardTypeLocator(evalContext.getBeanFactory().getBeanClassLoader())); + ConversionService conversionService = evalContext.getBeanFactory().getConversionService(); + if (conversionService != null) { + sec.setTypeConverter(new StandardTypeConverter(conversionService)); + } + customizeEvaluationContext(sec); + this.evaluationCache.put(evalContext, sec); + } + return expr.getValue(sec); + } + catch (Exception ex) { + throw new BeanExpressionException("Expression parsing failed", ex); + } + } + + /** + * Template method for customizing the expression evaluation context. + * <p>The default implementation is empty. + */ + protected void customizeEvaluationContext(StandardEvaluationContext evalContext) { + } + +} diff --git a/org.springframework.context/src/main/java/org/springframework/context/support/GenericXmlApplicationContext.java b/org.springframework.context/src/main/java/org/springframework/context/support/GenericXmlApplicationContext.java index b276ba04a03..00b65558499 100644 --- a/org.springframework.context/src/main/java/org/springframework/context/support/GenericXmlApplicationContext.java +++ b/org.springframework.context/src/main/java/org/springframework/context/support/GenericXmlApplicationContext.java @@ -1,134 +1,134 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.context.support; - -import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.io.ClassPathResource; -import org.springframework.core.io.Resource; - -/** - * Convenient application context with built-in XML support. - * This is a flexible alternative to {@link ClassPathXmlApplicationContext} - * and {@link FileSystemXmlApplicationContext}, to be configured via setters, - * with an eventual {@link #refresh()} call activating the context. - * - * <p>In case of multiple configuration files, bean definitions in later files - * will override those defined in earlier files. This can be leveraged to - * deliberately override certain bean definitions via an extra configuration file. - * - * @author Juergen Hoeller - * @author Chris Beams - * @since 3.0 - * @see #load - * @see XmlBeanDefinitionReader - * @see org.springframework.context.annotation.AnnotationConfigApplicationContext - */ -public class GenericXmlApplicationContext extends GenericApplicationContext { - - private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this); - - - /** - * Create a new GenericXmlApplicationContext that needs to be - * {@linkplain #load loaded} and then manually {@link #refresh refreshed}. - */ - public GenericXmlApplicationContext() { - reader.setEnvironment(this.getEnvironment()); - } - - /** - * Create a new GenericXmlApplicationContext, loading bean definitions - * from the given resources and automatically refreshing the context. - * @param resources the resources to load from - */ - public GenericXmlApplicationContext(Resource... resources) { - load(resources); - refresh(); - } - - /** - * Create a new GenericXmlApplicationContext, loading bean definitions - * from the given resource locations and automatically refreshing the context. - * @param resourceLocations the resources to load from - */ - public GenericXmlApplicationContext(String... resourceLocations) { - load(resourceLocations); - refresh(); - } - - /** - * Create a new GenericXmlApplicationContext, loading bean definitions - * from the given resource locations and automatically refreshing the context. - * @param relativeClass class whose package will be used as a prefix when - * loading each specified resource name - * @param resourceNames relatively-qualified names of resources to load - */ - public GenericXmlApplicationContext(Class<?> relativeClass, String... resourceNames) { - load(relativeClass, resourceNames); - refresh(); - } - - /** - * Set whether to use XML validation. Default is <code>true</code>. - */ - public void setValidating(boolean validating) { - this.reader.setValidating(validating); - } - - /** - * {@inheritDoc} - * <p>Delegates the given environment to underlying {@link XmlBeanDefinitionReader}. - * Should be called before any call to {@link #load}. - */ - @Override - public void setEnvironment(ConfigurableEnvironment environment) { - super.setEnvironment(environment); - this.reader.setEnvironment(this.getEnvironment()); - } - - /** - * Load bean definitions from the given XML resources. - * @param resources one or more resources to load from - */ - public void load(Resource... resources) { - this.reader.loadBeanDefinitions(resources); - } - - /** - * Load bean definitions from the given XML resources. - * @param resourceLocations one or more resource locations to load from - */ - public void load(String... resourceLocations) { - this.reader.loadBeanDefinitions(resourceLocations); - } - - /** - * Load bean definitions from the given XML resources. - * @param relativeClass class whose package will be used as a prefix when - * loading each specified resource name - * @param resourceNames relatively-qualified names of resources to load - */ - public void load(Class<?> relativeClass, String... resourceNames) { - Resource[] resources = new Resource[resourceNames.length]; - for (int i = 0; i < resourceNames.length; i++) { - resources[i] = new ClassPathResource(resourceNames[i], relativeClass); - } - this.load(resources); - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.context.support; + +import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; + +/** + * Convenient application context with built-in XML support. + * This is a flexible alternative to {@link ClassPathXmlApplicationContext} + * and {@link FileSystemXmlApplicationContext}, to be configured via setters, + * with an eventual {@link #refresh()} call activating the context. + * + * <p>In case of multiple configuration files, bean definitions in later files + * will override those defined in earlier files. This can be leveraged to + * deliberately override certain bean definitions via an extra configuration file. + * + * @author Juergen Hoeller + * @author Chris Beams + * @since 3.0 + * @see #load + * @see XmlBeanDefinitionReader + * @see org.springframework.context.annotation.AnnotationConfigApplicationContext + */ +public class GenericXmlApplicationContext extends GenericApplicationContext { + + private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this); + + + /** + * Create a new GenericXmlApplicationContext that needs to be + * {@linkplain #load loaded} and then manually {@link #refresh refreshed}. + */ + public GenericXmlApplicationContext() { + reader.setEnvironment(this.getEnvironment()); + } + + /** + * Create a new GenericXmlApplicationContext, loading bean definitions + * from the given resources and automatically refreshing the context. + * @param resources the resources to load from + */ + public GenericXmlApplicationContext(Resource... resources) { + load(resources); + refresh(); + } + + /** + * Create a new GenericXmlApplicationContext, loading bean definitions + * from the given resource locations and automatically refreshing the context. + * @param resourceLocations the resources to load from + */ + public GenericXmlApplicationContext(String... resourceLocations) { + load(resourceLocations); + refresh(); + } + + /** + * Create a new GenericXmlApplicationContext, loading bean definitions + * from the given resource locations and automatically refreshing the context. + * @param relativeClass class whose package will be used as a prefix when + * loading each specified resource name + * @param resourceNames relatively-qualified names of resources to load + */ + public GenericXmlApplicationContext(Class<?> relativeClass, String... resourceNames) { + load(relativeClass, resourceNames); + refresh(); + } + + /** + * Set whether to use XML validation. Default is <code>true</code>. + */ + public void setValidating(boolean validating) { + this.reader.setValidating(validating); + } + + /** + * {@inheritDoc} + * <p>Delegates the given environment to underlying {@link XmlBeanDefinitionReader}. + * Should be called before any call to {@link #load}. + */ + @Override + public void setEnvironment(ConfigurableEnvironment environment) { + super.setEnvironment(environment); + this.reader.setEnvironment(this.getEnvironment()); + } + + /** + * Load bean definitions from the given XML resources. + * @param resources one or more resources to load from + */ + public void load(Resource... resources) { + this.reader.loadBeanDefinitions(resources); + } + + /** + * Load bean definitions from the given XML resources. + * @param resourceLocations one or more resource locations to load from + */ + public void load(String... resourceLocations) { + this.reader.loadBeanDefinitions(resourceLocations); + } + + /** + * Load bean definitions from the given XML resources. + * @param relativeClass class whose package will be used as a prefix when + * loading each specified resource name + * @param resourceNames relatively-qualified names of resources to load + */ + public void load(Class<?> relativeClass, String... resourceNames) { + Resource[] resources = new Resource[resourceNames.length]; + for (int i = 0; i < resourceNames.length; i++) { + resources[i] = new ClassPathResource(resourceNames[i], relativeClass); + } + this.load(resources); + } + +} diff --git a/org.springframework.context/src/main/java/org/springframework/format/number/AbstractNumberFormatter.java b/org.springframework.context/src/main/java/org/springframework/format/number/AbstractNumberFormatter.java index 63795d6e80e..0d1d5aa973b 100644 --- a/org.springframework.context/src/main/java/org/springframework/format/number/AbstractNumberFormatter.java +++ b/org.springframework.context/src/main/java/org/springframework/format/number/AbstractNumberFormatter.java @@ -1,74 +1,74 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.format.number; - -import java.text.NumberFormat; -import java.text.ParseException; -import java.text.ParsePosition; -import java.util.Locale; - -import org.springframework.format.Formatter; - -/** - * Abstract formatter for Numbers, - * providing a {@link #getNumberFormat(java.util.Locale)} template method. - * - * @author Juergen Hoeller - * @author Keith Donald - * @since 3.0 - */ -public abstract class AbstractNumberFormatter implements Formatter<Number> { - - private boolean lenient = false; - - /** - * Specify whether or not parsing is to be lenient. Default is false. - * <p>With lenient parsing, the parser may allow inputs that do not precisely match the format. - * With strict parsing, inputs must match the format exactly. - */ - public void setLenient(boolean lenient) { - this.lenient = lenient; - } - - public String print(Number number, Locale locale) { - return getNumberFormat(locale).format(number); - } - - public Number parse(String text, Locale locale) throws ParseException { - NumberFormat format = getNumberFormat(locale); - ParsePosition position = new ParsePosition(0); - Number number = format.parse(text, position); - if (position.getErrorIndex() != -1) { - throw new ParseException(text, position.getIndex()); - } - if (!this.lenient) { - if (text.length() != position.getIndex()) { - // indicates a part of the string that was not parsed - throw new ParseException(text, position.getIndex()); - } - } - return number; - } - - /** - * Obtain a concrete NumberFormat for the specified locale. - * @param locale the current locale - * @return the NumberFormat instance (never <code>null</code>) - */ - protected abstract NumberFormat getNumberFormat(Locale locale); - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.format.number; + +import java.text.NumberFormat; +import java.text.ParseException; +import java.text.ParsePosition; +import java.util.Locale; + +import org.springframework.format.Formatter; + +/** + * Abstract formatter for Numbers, + * providing a {@link #getNumberFormat(java.util.Locale)} template method. + * + * @author Juergen Hoeller + * @author Keith Donald + * @since 3.0 + */ +public abstract class AbstractNumberFormatter implements Formatter<Number> { + + private boolean lenient = false; + + /** + * Specify whether or not parsing is to be lenient. Default is false. + * <p>With lenient parsing, the parser may allow inputs that do not precisely match the format. + * With strict parsing, inputs must match the format exactly. + */ + public void setLenient(boolean lenient) { + this.lenient = lenient; + } + + public String print(Number number, Locale locale) { + return getNumberFormat(locale).format(number); + } + + public Number parse(String text, Locale locale) throws ParseException { + NumberFormat format = getNumberFormat(locale); + ParsePosition position = new ParsePosition(0); + Number number = format.parse(text, position); + if (position.getErrorIndex() != -1) { + throw new ParseException(text, position.getIndex()); + } + if (!this.lenient) { + if (text.length() != position.getIndex()) { + // indicates a part of the string that was not parsed + throw new ParseException(text, position.getIndex()); + } + } + return number; + } + + /** + * Obtain a concrete NumberFormat for the specified locale. + * @param locale the current locale + * @return the NumberFormat instance (never <code>null</code>) + */ + protected abstract NumberFormat getNumberFormat(Locale locale); + +} diff --git a/org.springframework.context/src/main/java/org/springframework/instrument/classloading/glassfish/GlassFishClassLoaderAdapter.java b/org.springframework.context/src/main/java/org/springframework/instrument/classloading/glassfish/GlassFishClassLoaderAdapter.java index 550ef939fb2..8d114b2bec2 100644 --- a/org.springframework.context/src/main/java/org/springframework/instrument/classloading/glassfish/GlassFishClassLoaderAdapter.java +++ b/org.springframework.context/src/main/java/org/springframework/instrument/classloading/glassfish/GlassFishClassLoaderAdapter.java @@ -1,128 +1,128 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.instrument.classloading.glassfish; - -import java.lang.instrument.ClassFileTransformer; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -/** - * Reflective wrapper around the GlassFish class loader. Used to - * encapsulate the classloader-specific methods (discovered and - * called through reflection) from the load-time weaver. - * - * <p>Supports GlassFish V1, V2 and V3 (currently in beta). - * - * @author Costin Leau - * @since 3.0 - */ -class GlassFishClassLoaderAdapter { - - static final String INSTRUMENTABLE_CLASSLOADER_GLASSFISH_V2 = "com.sun.enterprise.loader.InstrumentableClassLoader"; - - static final String INSTRUMENTABLE_CLASSLOADER_GLASSFISH_V3 = "org.glassfish.api.deployment.InstrumentableClassLoader"; - - private static final String CLASS_TRANSFORMER = "javax.persistence.spi.ClassTransformer"; - - - private final ClassLoader classLoader; - - private final Method addTransformer; - - private final Method copy; - - private final boolean glassFishV3; - - - public GlassFishClassLoaderAdapter(ClassLoader classLoader) { - Class<?> instrumentableLoaderClass; - boolean glassV3 = false; - try { - // try the V1/V2 API first - instrumentableLoaderClass = classLoader.loadClass(INSTRUMENTABLE_CLASSLOADER_GLASSFISH_V2); - } - catch (ClassNotFoundException ex) { - // fall back to V3 - try { - instrumentableLoaderClass = classLoader.loadClass(INSTRUMENTABLE_CLASSLOADER_GLASSFISH_V3); - glassV3 = true; - } - catch (ClassNotFoundException cnfe) { - throw new IllegalStateException("Could not initialize GlassFish LoadTimeWeaver because " + - "GlassFish (V1, V2 or V3) API classes are not available", ex); - } - } - try { - Class<?> classTransformerClass = - (glassV3 ? ClassFileTransformer.class : classLoader.loadClass(CLASS_TRANSFORMER)); - - this.addTransformer = instrumentableLoaderClass.getMethod("addTransformer", classTransformerClass); - this.copy = instrumentableLoaderClass.getMethod("copy"); - } - catch (Exception ex) { - throw new IllegalStateException( - "Could not initialize GlassFish LoadTimeWeaver because GlassFish API classes are not available", ex); - } - - ClassLoader clazzLoader = null; - // Detect transformation-aware ClassLoader by traversing the hierarchy - // (as in GlassFish, Spring can be loaded by the WebappClassLoader). - for (ClassLoader cl = classLoader; cl != null && clazzLoader == null; cl = cl.getParent()) { - if (instrumentableLoaderClass.isInstance(cl)) { - clazzLoader = cl; - } - } - - if (clazzLoader == null) { - throw new IllegalArgumentException(classLoader + " and its parents are not suitable ClassLoaders: A [" + - instrumentableLoaderClass.getName() + "] implementation is required."); - } - - this.classLoader = clazzLoader; - this.glassFishV3 = glassV3; - } - - public void addTransformer(ClassFileTransformer transformer) { - try { - this.addTransformer.invoke(this.classLoader, - (this.glassFishV3 ? transformer : new ClassTransformerAdapter(transformer))); - } - catch (InvocationTargetException ex) { - throw new IllegalStateException("GlassFish addTransformer method threw exception ", ex.getCause()); - } - catch (Exception ex) { - throw new IllegalStateException("Could not invoke GlassFish addTransformer method", ex); - } - } - - public ClassLoader getClassLoader() { - return this.classLoader; - } - - public ClassLoader getThrowawayClassLoader() { - try { - return (ClassLoader) this.copy.invoke(this.classLoader); - } - catch (InvocationTargetException ex) { - throw new IllegalStateException("GlassFish copy method threw exception ", ex.getCause()); - } - catch (Exception ex) { - throw new IllegalStateException("Could not invoke GlassFish copy method", ex); - } - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.instrument.classloading.glassfish; + +import java.lang.instrument.ClassFileTransformer; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * Reflective wrapper around the GlassFish class loader. Used to + * encapsulate the classloader-specific methods (discovered and + * called through reflection) from the load-time weaver. + * + * <p>Supports GlassFish V1, V2 and V3 (currently in beta). + * + * @author Costin Leau + * @since 3.0 + */ +class GlassFishClassLoaderAdapter { + + static final String INSTRUMENTABLE_CLASSLOADER_GLASSFISH_V2 = "com.sun.enterprise.loader.InstrumentableClassLoader"; + + static final String INSTRUMENTABLE_CLASSLOADER_GLASSFISH_V3 = "org.glassfish.api.deployment.InstrumentableClassLoader"; + + private static final String CLASS_TRANSFORMER = "javax.persistence.spi.ClassTransformer"; + + + private final ClassLoader classLoader; + + private final Method addTransformer; + + private final Method copy; + + private final boolean glassFishV3; + + + public GlassFishClassLoaderAdapter(ClassLoader classLoader) { + Class<?> instrumentableLoaderClass; + boolean glassV3 = false; + try { + // try the V1/V2 API first + instrumentableLoaderClass = classLoader.loadClass(INSTRUMENTABLE_CLASSLOADER_GLASSFISH_V2); + } + catch (ClassNotFoundException ex) { + // fall back to V3 + try { + instrumentableLoaderClass = classLoader.loadClass(INSTRUMENTABLE_CLASSLOADER_GLASSFISH_V3); + glassV3 = true; + } + catch (ClassNotFoundException cnfe) { + throw new IllegalStateException("Could not initialize GlassFish LoadTimeWeaver because " + + "GlassFish (V1, V2 or V3) API classes are not available", ex); + } + } + try { + Class<?> classTransformerClass = + (glassV3 ? ClassFileTransformer.class : classLoader.loadClass(CLASS_TRANSFORMER)); + + this.addTransformer = instrumentableLoaderClass.getMethod("addTransformer", classTransformerClass); + this.copy = instrumentableLoaderClass.getMethod("copy"); + } + catch (Exception ex) { + throw new IllegalStateException( + "Could not initialize GlassFish LoadTimeWeaver because GlassFish API classes are not available", ex); + } + + ClassLoader clazzLoader = null; + // Detect transformation-aware ClassLoader by traversing the hierarchy + // (as in GlassFish, Spring can be loaded by the WebappClassLoader). + for (ClassLoader cl = classLoader; cl != null && clazzLoader == null; cl = cl.getParent()) { + if (instrumentableLoaderClass.isInstance(cl)) { + clazzLoader = cl; + } + } + + if (clazzLoader == null) { + throw new IllegalArgumentException(classLoader + " and its parents are not suitable ClassLoaders: A [" + + instrumentableLoaderClass.getName() + "] implementation is required."); + } + + this.classLoader = clazzLoader; + this.glassFishV3 = glassV3; + } + + public void addTransformer(ClassFileTransformer transformer) { + try { + this.addTransformer.invoke(this.classLoader, + (this.glassFishV3 ? transformer : new ClassTransformerAdapter(transformer))); + } + catch (InvocationTargetException ex) { + throw new IllegalStateException("GlassFish addTransformer method threw exception ", ex.getCause()); + } + catch (Exception ex) { + throw new IllegalStateException("Could not invoke GlassFish addTransformer method", ex); + } + } + + public ClassLoader getClassLoader() { + return this.classLoader; + } + + public ClassLoader getThrowawayClassLoader() { + try { + return (ClassLoader) this.copy.invoke(this.classLoader); + } + catch (InvocationTargetException ex) { + throw new IllegalStateException("GlassFish copy method threw exception ", ex.getCause()); + } + catch (Exception ex) { + throw new IllegalStateException("Could not invoke GlassFish copy method", ex); + } + } + +} diff --git a/org.springframework.context/src/main/java/org/springframework/instrument/classloading/jboss/JBossClassLoaderAdapter.java b/org.springframework.context/src/main/java/org/springframework/instrument/classloading/jboss/JBossClassLoaderAdapter.java index 38126a76cdb..e4b448017e9 100644 --- a/org.springframework.context/src/main/java/org/springframework/instrument/classloading/jboss/JBossClassLoaderAdapter.java +++ b/org.springframework.context/src/main/java/org/springframework/instrument/classloading/jboss/JBossClassLoaderAdapter.java @@ -1,33 +1,33 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.instrument.classloading.jboss; - -import java.lang.instrument.ClassFileTransformer; - -/** - * Simple interface used for handling the different JBoss class loader adapters. - * - * @author Costin Leau - * @since 3.1 - */ -interface JBossClassLoaderAdapter { - - void addTransformer(ClassFileTransformer transformer); - - ClassLoader getInstrumentableClassLoader(); - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.instrument.classloading.jboss; + +import java.lang.instrument.ClassFileTransformer; + +/** + * Simple interface used for handling the different JBoss class loader adapters. + * + * @author Costin Leau + * @since 3.1 + */ +interface JBossClassLoaderAdapter { + + void addTransformer(ClassFileTransformer transformer); + + ClassLoader getInstrumentableClassLoader(); + +} diff --git a/org.springframework.context/src/main/java/org/springframework/instrument/classloading/jboss/JBossLoadTimeWeaver.java b/org.springframework.context/src/main/java/org/springframework/instrument/classloading/jboss/JBossLoadTimeWeaver.java index b182c7181cf..243724af27d 100644 --- a/org.springframework.context/src/main/java/org/springframework/instrument/classloading/jboss/JBossLoadTimeWeaver.java +++ b/org.springframework.context/src/main/java/org/springframework/instrument/classloading/jboss/JBossLoadTimeWeaver.java @@ -1,91 +1,91 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.instrument.classloading.jboss; - -import java.lang.instrument.ClassFileTransformer; - -import org.springframework.instrument.classloading.LoadTimeWeaver; -import org.springframework.instrument.classloading.SimpleThrowawayClassLoader; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; - -/** - * {@link LoadTimeWeaver} implementation for JBoss's instrumentable ClassLoader. - * Autodetects the specific JBoss version at runtime: currently supports - * JBoss AS 5, 6 and 7 (as of Spring 3.1). - * - * <p><b>NOTE:</b> On JBoss 6.0, to avoid the container loading the classes before the - * application actually starts, one needs to add a <tt>WEB-INF/jboss-scanning.xml</tt> - * file to the application archive - with the following content: - * <pre><scanning xmlns="urn:jboss:scanning:1.0"/></pre> - * - * <p>Thanks to Ales Justin and Marius Bogoevici for the initial prototype. - * - * @author Costin Leau - * @since 3.0 - */ -public class JBossLoadTimeWeaver implements LoadTimeWeaver { - - private final JBossClassLoaderAdapter adapter; - - - /** - * Create a new instance of the {@link JBossLoadTimeWeaver} class using - * the default {@link ClassLoader class loader}. - * @see org.springframework.util.ClassUtils#getDefaultClassLoader() - */ - public JBossLoadTimeWeaver() { - this(ClassUtils.getDefaultClassLoader()); - } - - /** - * Create a new instance of the {@link JBossLoadTimeWeaver} class using - * the supplied {@link ClassLoader}. - * @param classLoader the <code>ClassLoader</code> to delegate to for - * weaving (must not be <code>null</code>) - */ - public JBossLoadTimeWeaver(ClassLoader classLoader) { - Assert.notNull(classLoader, "ClassLoader must not be null"); - String loaderClassName = classLoader.getClass().getName(); - - if (loaderClassName.startsWith("org.jboss.classloader")) { - // JBoss AS 5 or JBoss AS 6 - this.adapter = new JBossMCAdapter(classLoader); - } - else if (loaderClassName.startsWith("org.jboss.modules")) { - // JBoss AS 7 - this.adapter = new JBossModulesAdapter(classLoader); - } - else { - throw new IllegalArgumentException("Unexpected ClassLoader type: " + loaderClassName); - } - } - - - public void addTransformer(ClassFileTransformer transformer) { - this.adapter.addTransformer(transformer); - } - - public ClassLoader getInstrumentableClassLoader() { - return this.adapter.getInstrumentableClassLoader(); - } - - public ClassLoader getThrowawayClassLoader() { - return new SimpleThrowawayClassLoader(getInstrumentableClassLoader()); - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.instrument.classloading.jboss; + +import java.lang.instrument.ClassFileTransformer; + +import org.springframework.instrument.classloading.LoadTimeWeaver; +import org.springframework.instrument.classloading.SimpleThrowawayClassLoader; +import org.springframework.util.Assert; +import org.springframework.util.ClassUtils; + +/** + * {@link LoadTimeWeaver} implementation for JBoss's instrumentable ClassLoader. + * Autodetects the specific JBoss version at runtime: currently supports + * JBoss AS 5, 6 and 7 (as of Spring 3.1). + * + * <p><b>NOTE:</b> On JBoss 6.0, to avoid the container loading the classes before the + * application actually starts, one needs to add a <tt>WEB-INF/jboss-scanning.xml</tt> + * file to the application archive - with the following content: + * <pre><scanning xmlns="urn:jboss:scanning:1.0"/></pre> + * + * <p>Thanks to Ales Justin and Marius Bogoevici for the initial prototype. + * + * @author Costin Leau + * @since 3.0 + */ +public class JBossLoadTimeWeaver implements LoadTimeWeaver { + + private final JBossClassLoaderAdapter adapter; + + + /** + * Create a new instance of the {@link JBossLoadTimeWeaver} class using + * the default {@link ClassLoader class loader}. + * @see org.springframework.util.ClassUtils#getDefaultClassLoader() + */ + public JBossLoadTimeWeaver() { + this(ClassUtils.getDefaultClassLoader()); + } + + /** + * Create a new instance of the {@link JBossLoadTimeWeaver} class using + * the supplied {@link ClassLoader}. + * @param classLoader the <code>ClassLoader</code> to delegate to for + * weaving (must not be <code>null</code>) + */ + public JBossLoadTimeWeaver(ClassLoader classLoader) { + Assert.notNull(classLoader, "ClassLoader must not be null"); + String loaderClassName = classLoader.getClass().getName(); + + if (loaderClassName.startsWith("org.jboss.classloader")) { + // JBoss AS 5 or JBoss AS 6 + this.adapter = new JBossMCAdapter(classLoader); + } + else if (loaderClassName.startsWith("org.jboss.modules")) { + // JBoss AS 7 + this.adapter = new JBossModulesAdapter(classLoader); + } + else { + throw new IllegalArgumentException("Unexpected ClassLoader type: " + loaderClassName); + } + } + + + public void addTransformer(ClassFileTransformer transformer) { + this.adapter.addTransformer(transformer); + } + + public ClassLoader getInstrumentableClassLoader() { + return this.adapter.getInstrumentableClassLoader(); + } + + public ClassLoader getThrowawayClassLoader() { + return new SimpleThrowawayClassLoader(getInstrumentableClassLoader()); + } + +} diff --git a/org.springframework.context/src/main/java/org/springframework/instrument/classloading/jboss/JBossMCAdapter.java b/org.springframework.context/src/main/java/org/springframework/instrument/classloading/jboss/JBossMCAdapter.java index 4e7d16bcfd4..5216b5cd508 100644 --- a/org.springframework.context/src/main/java/org/springframework/instrument/classloading/jboss/JBossMCAdapter.java +++ b/org.springframework.context/src/main/java/org/springframework/instrument/classloading/jboss/JBossMCAdapter.java @@ -1,145 +1,145 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.instrument.classloading.jboss; - -import java.lang.instrument.ClassFileTransformer; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; - -import org.springframework.util.Assert; -import org.springframework.util.ReflectionUtils; - -/** - * Reflective wrapper around a JBoss 5 and 6 class loader methods (discovered and called - * through reflection) for load time weaving. - * - * @author Costin Leau - * @since 3.1 - */ -class JBossMCAdapter implements JBossClassLoaderAdapter { - - private static final String TRANSLATOR_NAME = "org.jboss.util.loading.Translator"; - private static final String POLICY_NAME = "org.jboss.classloader.spi.base.BaseClassLoaderPolicy"; - private static final String DOMAIN_NAME = "org.jboss.classloader.spi.base.BaseClassLoaderDomain"; - private static final String DEDICATED_SYSTEM = "org.jboss.classloader.spi.ClassLoaderSystem"; - private static final String LOADER_NAME = "org.jboss.classloader.spi.base.BaseClassLoader"; - private static final String GET_POLICY = "getPolicy"; - private static final String GET_DOMAIN = "getClassLoaderDomain"; - private static final String GET_SYSTEM = "getClassLoaderSystem"; - - // available since JBoss AS 5.1.0 / MC 2.0.6 (allows multiple transformers to be added) - private static final String ADD_TRANSLATOR_NAME = "addTranslator"; - // available since JBoss AS 5.0.0 / MC 2.0.1 (allows only one transformer to be added) - private static final String SET_TRANSLATOR_NAME = "setTranslator"; - - private final ClassLoader classLoader; - private final Class<?> translatorClass; - - private final Method addTranslator; - private final Object target; - - JBossMCAdapter(ClassLoader classLoader) { - Class<?> clazzLoaderType = null; - try { - // resolve BaseClassLoader.class - clazzLoaderType = classLoader.loadClass(LOADER_NAME); - - ClassLoader clazzLoader = null; - // walk the hierarchy to detect the instrumentation aware classloader - for (ClassLoader cl = classLoader; cl != null && clazzLoader == null; cl = cl.getParent()) { - if (clazzLoaderType.isInstance(cl)) { - clazzLoader = cl; - } - } - - if (clazzLoader == null) { - throw new IllegalArgumentException(classLoader + " and its parents are not suitable ClassLoaders: " - + "A [" + LOADER_NAME + "] implementation is required."); - } - - this.classLoader = clazzLoader; - // use the classloader that loaded the classloader to load - // the types for reflection purposes - classLoader = clazzLoader.getClass().getClassLoader(); - - // BaseClassLoader#getPolicy - Method method = clazzLoaderType.getDeclaredMethod(GET_POLICY); - ReflectionUtils.makeAccessible(method); - Object policy = method.invoke(this.classLoader); - - Object addTarget = null; - Method addMethod = null; - - // try the 5.1.x hooks - // check existence of BaseClassLoaderPolicy#addTranslator(Translator) - this.translatorClass = classLoader.loadClass(TRANSLATOR_NAME); - Class<?> clazz = classLoader.loadClass(POLICY_NAME); - try { - addMethod = clazz.getDeclaredMethod(ADD_TRANSLATOR_NAME, translatorClass); - addTarget = policy; - } catch (NoSuchMethodException ex) { - } - - // fall back to 5.0.x method - if (addMethod == null) { - - // BaseClassLoaderPolicy#getClassLoaderDomain - method = clazz.getDeclaredMethod(GET_DOMAIN); - ReflectionUtils.makeAccessible(method); - Object domain = method.invoke(policy); - - // BaseClassLoaderDomain#getClassLoaderSystem - clazz = classLoader.loadClass(DOMAIN_NAME); - method = clazz.getDeclaredMethod(GET_SYSTEM); - ReflectionUtils.makeAccessible(method); - Object system = method.invoke(domain); - - // resolve ClassLoaderSystem - clazz = classLoader.loadClass(DEDICATED_SYSTEM); - Assert.isInstanceOf(clazz, system, "JBoss LoadTimeWeaver requires JBoss loader system of type " - + clazz.getName() + " on JBoss 5.0.x"); - - // ClassLoaderSystem#setTranslator - addMethod = clazz.getDeclaredMethod(SET_TRANSLATOR_NAME, translatorClass); - addTarget = system; - } - - this.addTranslator = addMethod; - this.target = addTarget; - - } catch (Exception ex) { - throw new IllegalStateException( - "Could not initialize JBoss LoadTimeWeaver because the JBoss 5 API classes are not available", ex); - } - } - - public void addTransformer(ClassFileTransformer transformer) { - InvocationHandler adapter = new JBossMCTranslatorAdapter(transformer); - Object adapterInstance = Proxy.newProxyInstance(this.translatorClass.getClassLoader(), - new Class[] { this.translatorClass }, adapter); - - try { - addTranslator.invoke(target, adapterInstance); - } catch (Exception ex) { - throw new IllegalStateException("Could not add transformer on JBoss 5/6 classloader " + classLoader, ex); - } - } - - public ClassLoader getInstrumentableClassLoader() { - return classLoader; - } +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.instrument.classloading.jboss; + +import java.lang.instrument.ClassFileTransformer; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +import org.springframework.util.Assert; +import org.springframework.util.ReflectionUtils; + +/** + * Reflective wrapper around a JBoss 5 and 6 class loader methods (discovered and called + * through reflection) for load time weaving. + * + * @author Costin Leau + * @since 3.1 + */ +class JBossMCAdapter implements JBossClassLoaderAdapter { + + private static final String TRANSLATOR_NAME = "org.jboss.util.loading.Translator"; + private static final String POLICY_NAME = "org.jboss.classloader.spi.base.BaseClassLoaderPolicy"; + private static final String DOMAIN_NAME = "org.jboss.classloader.spi.base.BaseClassLoaderDomain"; + private static final String DEDICATED_SYSTEM = "org.jboss.classloader.spi.ClassLoaderSystem"; + private static final String LOADER_NAME = "org.jboss.classloader.spi.base.BaseClassLoader"; + private static final String GET_POLICY = "getPolicy"; + private static final String GET_DOMAIN = "getClassLoaderDomain"; + private static final String GET_SYSTEM = "getClassLoaderSystem"; + + // available since JBoss AS 5.1.0 / MC 2.0.6 (allows multiple transformers to be added) + private static final String ADD_TRANSLATOR_NAME = "addTranslator"; + // available since JBoss AS 5.0.0 / MC 2.0.1 (allows only one transformer to be added) + private static final String SET_TRANSLATOR_NAME = "setTranslator"; + + private final ClassLoader classLoader; + private final Class<?> translatorClass; + + private final Method addTranslator; + private final Object target; + + JBossMCAdapter(ClassLoader classLoader) { + Class<?> clazzLoaderType = null; + try { + // resolve BaseClassLoader.class + clazzLoaderType = classLoader.loadClass(LOADER_NAME); + + ClassLoader clazzLoader = null; + // walk the hierarchy to detect the instrumentation aware classloader + for (ClassLoader cl = classLoader; cl != null && clazzLoader == null; cl = cl.getParent()) { + if (clazzLoaderType.isInstance(cl)) { + clazzLoader = cl; + } + } + + if (clazzLoader == null) { + throw new IllegalArgumentException(classLoader + " and its parents are not suitable ClassLoaders: " + + "A [" + LOADER_NAME + "] implementation is required."); + } + + this.classLoader = clazzLoader; + // use the classloader that loaded the classloader to load + // the types for reflection purposes + classLoader = clazzLoader.getClass().getClassLoader(); + + // BaseClassLoader#getPolicy + Method method = clazzLoaderType.getDeclaredMethod(GET_POLICY); + ReflectionUtils.makeAccessible(method); + Object policy = method.invoke(this.classLoader); + + Object addTarget = null; + Method addMethod = null; + + // try the 5.1.x hooks + // check existence of BaseClassLoaderPolicy#addTranslator(Translator) + this.translatorClass = classLoader.loadClass(TRANSLATOR_NAME); + Class<?> clazz = classLoader.loadClass(POLICY_NAME); + try { + addMethod = clazz.getDeclaredMethod(ADD_TRANSLATOR_NAME, translatorClass); + addTarget = policy; + } catch (NoSuchMethodException ex) { + } + + // fall back to 5.0.x method + if (addMethod == null) { + + // BaseClassLoaderPolicy#getClassLoaderDomain + method = clazz.getDeclaredMethod(GET_DOMAIN); + ReflectionUtils.makeAccessible(method); + Object domain = method.invoke(policy); + + // BaseClassLoaderDomain#getClassLoaderSystem + clazz = classLoader.loadClass(DOMAIN_NAME); + method = clazz.getDeclaredMethod(GET_SYSTEM); + ReflectionUtils.makeAccessible(method); + Object system = method.invoke(domain); + + // resolve ClassLoaderSystem + clazz = classLoader.loadClass(DEDICATED_SYSTEM); + Assert.isInstanceOf(clazz, system, "JBoss LoadTimeWeaver requires JBoss loader system of type " + + clazz.getName() + " on JBoss 5.0.x"); + + // ClassLoaderSystem#setTranslator + addMethod = clazz.getDeclaredMethod(SET_TRANSLATOR_NAME, translatorClass); + addTarget = system; + } + + this.addTranslator = addMethod; + this.target = addTarget; + + } catch (Exception ex) { + throw new IllegalStateException( + "Could not initialize JBoss LoadTimeWeaver because the JBoss 5 API classes are not available", ex); + } + } + + public void addTransformer(ClassFileTransformer transformer) { + InvocationHandler adapter = new JBossMCTranslatorAdapter(transformer); + Object adapterInstance = Proxy.newProxyInstance(this.translatorClass.getClassLoader(), + new Class[] { this.translatorClass }, adapter); + + try { + addTranslator.invoke(target, adapterInstance); + } catch (Exception ex) { + throw new IllegalStateException("Could not add transformer on JBoss 5/6 classloader " + classLoader, ex); + } + } + + public ClassLoader getInstrumentableClassLoader() { + return classLoader; + } } \ No newline at end of file diff --git a/org.springframework.context/src/main/java/org/springframework/instrument/classloading/jboss/JBossMCTranslatorAdapter.java b/org.springframework.context/src/main/java/org/springframework/instrument/classloading/jboss/JBossMCTranslatorAdapter.java index 16570a514fc..794864e5f6e 100644 --- a/org.springframework.context/src/main/java/org/springframework/instrument/classloading/jboss/JBossMCTranslatorAdapter.java +++ b/org.springframework.context/src/main/java/org/springframework/instrument/classloading/jboss/JBossMCTranslatorAdapter.java @@ -1,82 +1,82 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.instrument.classloading.jboss; - -import java.lang.instrument.ClassFileTransformer; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.security.ProtectionDomain; - -/** - * Adapter that implements JBoss Translator interface, delegating to a - * standard JDK {@link ClassFileTransformer} underneath. - * - * <p>To avoid compile time checks again the vendor API, a dynamic proxy is - * being used. - * - * @author Costin Leau - * @since 3.1 - */ -class JBossMCTranslatorAdapter implements InvocationHandler { - - private final ClassFileTransformer transformer; - - /** - * Creates a new {@link JBossMCTranslatorAdapter}. - * @param transformer the {@link ClassFileTransformer} to be adapted (must - * not be <code>null</code>) - */ - public JBossMCTranslatorAdapter(ClassFileTransformer transformer) { - this.transformer = transformer; - } - - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - String name = method.getName(); - - if ("equals".equals(name)) { - return (Boolean.valueOf(proxy == args[0])); - } else if ("hashCode".equals(name)) { - return hashCode(); - } else if ("toString".equals(name)) { - return toString(); - } else if ("transform".equals(name)) { - return transform((ClassLoader) args[0], (String) args[1], (Class<?>) args[2], (ProtectionDomain) args[3], - (byte[]) args[4]); - } else if ("unregisterClassLoader".equals(name)) { - unregisterClassLoader((ClassLoader) args[0]); - return null; - - } else { - throw new IllegalArgumentException("Unknown method: " + method); - } - } - - public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, - ProtectionDomain protectionDomain, byte[] classfileBuffer) throws Exception { - return transformer.transform(loader, className, classBeingRedefined, protectionDomain, classfileBuffer); - } - - public void unregisterClassLoader(ClassLoader loader) { - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(getClass().getName()); - builder.append(" for transformer: "); - builder.append(this.transformer); - return builder.toString(); - } +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.instrument.classloading.jboss; + +import java.lang.instrument.ClassFileTransformer; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.security.ProtectionDomain; + +/** + * Adapter that implements JBoss Translator interface, delegating to a + * standard JDK {@link ClassFileTransformer} underneath. + * + * <p>To avoid compile time checks again the vendor API, a dynamic proxy is + * being used. + * + * @author Costin Leau + * @since 3.1 + */ +class JBossMCTranslatorAdapter implements InvocationHandler { + + private final ClassFileTransformer transformer; + + /** + * Creates a new {@link JBossMCTranslatorAdapter}. + * @param transformer the {@link ClassFileTransformer} to be adapted (must + * not be <code>null</code>) + */ + public JBossMCTranslatorAdapter(ClassFileTransformer transformer) { + this.transformer = transformer; + } + + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + String name = method.getName(); + + if ("equals".equals(name)) { + return (Boolean.valueOf(proxy == args[0])); + } else if ("hashCode".equals(name)) { + return hashCode(); + } else if ("toString".equals(name)) { + return toString(); + } else if ("transform".equals(name)) { + return transform((ClassLoader) args[0], (String) args[1], (Class<?>) args[2], (ProtectionDomain) args[3], + (byte[]) args[4]); + } else if ("unregisterClassLoader".equals(name)) { + unregisterClassLoader((ClassLoader) args[0]); + return null; + + } else { + throw new IllegalArgumentException("Unknown method: " + method); + } + } + + public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, + ProtectionDomain protectionDomain, byte[] classfileBuffer) throws Exception { + return transformer.transform(loader, className, classBeingRedefined, protectionDomain, classfileBuffer); + } + + public void unregisterClassLoader(ClassLoader loader) { + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(getClass().getName()); + builder.append(" for transformer: "); + builder.append(this.transformer); + return builder.toString(); + } } \ No newline at end of file diff --git a/org.springframework.context/src/main/java/org/springframework/instrument/classloading/jboss/JBossModulesAdapter.java b/org.springframework.context/src/main/java/org/springframework/instrument/classloading/jboss/JBossModulesAdapter.java index be0291d59dc..f9ba2b62045 100644 --- a/org.springframework.context/src/main/java/org/springframework/instrument/classloading/jboss/JBossModulesAdapter.java +++ b/org.springframework.context/src/main/java/org/springframework/instrument/classloading/jboss/JBossModulesAdapter.java @@ -1,71 +1,71 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.instrument.classloading.jboss; - -import java.lang.instrument.ClassFileTransformer; -import java.lang.reflect.Field; -import java.lang.reflect.Method; - -import org.springframework.util.Assert; -import org.springframework.util.ReflectionUtils; - -/** - * JBoss 7 adapter. - * - * @author Costin Leau - * @since 3.1 - */ -class JBossModulesAdapter implements JBossClassLoaderAdapter { - - private static final String TRANSFORMER_FIELD_NAME = "transformer"; - private static final String TRANSFORMER_ADD_METHOD_NAME = "addTransformer"; - private static final String DELEGATING_TRANSFORMER_CLASS_NAME = "org.jboss.as.server.deployment.module.DelegatingClassFileTransformer"; - private final ClassLoader classLoader; - private final Method addTransformer; - private final Object delegatingTransformer; - - public JBossModulesAdapter(ClassLoader loader) { - this.classLoader = loader; - - try { - Field transformers = ReflectionUtils.findField(classLoader.getClass(), TRANSFORMER_FIELD_NAME); - transformers.setAccessible(true); - - delegatingTransformer = transformers.get(classLoader); - - Assert.state(delegatingTransformer.getClass().getName().equals(DELEGATING_TRANSFORMER_CLASS_NAME), - "Transformer not of the expected type: " + delegatingTransformer.getClass().getName()); - addTransformer = ReflectionUtils.findMethod(delegatingTransformer.getClass(), TRANSFORMER_ADD_METHOD_NAME, - ClassFileTransformer.class); - addTransformer.setAccessible(true); - } catch (Exception ex) { - throw new IllegalStateException("Could not initialize JBoss 7 LoadTimeWeaver", ex); - } - } - - public void addTransformer(ClassFileTransformer transformer) { - try { - addTransformer.invoke(delegatingTransformer, transformer); - } catch (Exception ex) { - throw new IllegalStateException("Could not add transformer on JBoss 7 classloader " + classLoader, ex); - } - } - - public ClassLoader getInstrumentableClassLoader() { - return classLoader; - } +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.instrument.classloading.jboss; + +import java.lang.instrument.ClassFileTransformer; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +import org.springframework.util.Assert; +import org.springframework.util.ReflectionUtils; + +/** + * JBoss 7 adapter. + * + * @author Costin Leau + * @since 3.1 + */ +class JBossModulesAdapter implements JBossClassLoaderAdapter { + + private static final String TRANSFORMER_FIELD_NAME = "transformer"; + private static final String TRANSFORMER_ADD_METHOD_NAME = "addTransformer"; + private static final String DELEGATING_TRANSFORMER_CLASS_NAME = "org.jboss.as.server.deployment.module.DelegatingClassFileTransformer"; + private final ClassLoader classLoader; + private final Method addTransformer; + private final Object delegatingTransformer; + + public JBossModulesAdapter(ClassLoader loader) { + this.classLoader = loader; + + try { + Field transformers = ReflectionUtils.findField(classLoader.getClass(), TRANSFORMER_FIELD_NAME); + transformers.setAccessible(true); + + delegatingTransformer = transformers.get(classLoader); + + Assert.state(delegatingTransformer.getClass().getName().equals(DELEGATING_TRANSFORMER_CLASS_NAME), + "Transformer not of the expected type: " + delegatingTransformer.getClass().getName()); + addTransformer = ReflectionUtils.findMethod(delegatingTransformer.getClass(), TRANSFORMER_ADD_METHOD_NAME, + ClassFileTransformer.class); + addTransformer.setAccessible(true); + } catch (Exception ex) { + throw new IllegalStateException("Could not initialize JBoss 7 LoadTimeWeaver", ex); + } + } + + public void addTransformer(ClassFileTransformer transformer) { + try { + addTransformer.invoke(delegatingTransformer, transformer); + } catch (Exception ex) { + throw new IllegalStateException("Could not add transformer on JBoss 7 classloader " + classLoader, ex); + } + } + + public ClassLoader getInstrumentableClassLoader() { + return classLoader; + } } \ No newline at end of file diff --git a/org.springframework.context/src/main/java/org/springframework/instrument/classloading/jboss/package-info.java b/org.springframework.context/src/main/java/org/springframework/instrument/classloading/jboss/package-info.java index 0c861f32e92..4072d51f6ca 100644 --- a/org.springframework.context/src/main/java/org/springframework/instrument/classloading/jboss/package-info.java +++ b/org.springframework.context/src/main/java/org/springframework/instrument/classloading/jboss/package-info.java @@ -1,8 +1,8 @@ - -/** - * - * Support for class instrumentation on JBoss AS 5.x / JBoss MC 2.0.x. - * - */ -package org.springframework.instrument.classloading.jboss; - + +/** + * + * Support for class instrumentation on JBoss AS 5.x / JBoss MC 2.0.x. + * + */ +package org.springframework.instrument.classloading.jboss; + diff --git a/org.springframework.context/src/main/java/org/springframework/instrument/classloading/oc4j/OC4JClassLoaderAdapter.java b/org.springframework.context/src/main/java/org/springframework/instrument/classloading/oc4j/OC4JClassLoaderAdapter.java index 15b1a41fc28..c1383385182 100644 --- a/org.springframework.context/src/main/java/org/springframework/instrument/classloading/oc4j/OC4JClassLoaderAdapter.java +++ b/org.springframework.context/src/main/java/org/springframework/instrument/classloading/oc4j/OC4JClassLoaderAdapter.java @@ -1,88 +1,88 @@ -/* - * Copyright 2006-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.instrument.classloading.oc4j; - -import java.lang.instrument.ClassFileTransformer; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; - -import org.springframework.util.Assert; - -/** - * Reflective wrapper around a OC4J class loader. Used to - * encapsulate the classloader-specific methods (discovered and - * called through reflection) from the load-time weaver. - * - * @author Costin Leau - */ -class OC4JClassLoaderAdapter { - - private static final String CL_UTILS = "oracle.classloader.util.ClassLoaderUtilities"; - private static final String PREPROCESS_UTILS = "oracle.classloader.util.ClassPreprocessor"; - - private final ClassLoader classLoader; - private final Class<?> processorClass; - private final Method addTransformer; - private final Method copy; - - public OC4JClassLoaderAdapter(ClassLoader classLoader) { - try { - // Since OC4J 10.1.3's PolicyClassLoader is going to be removed, - // we rely on the ClassLoaderUtilities API instead. - Class<?> utilClass = classLoader.loadClass(CL_UTILS); - this.processorClass = classLoader.loadClass(PREPROCESS_UTILS); - - this.addTransformer = utilClass.getMethod("addPreprocessor", new Class[] { ClassLoader.class, - this.processorClass }); - this.copy = utilClass.getMethod("copy", new Class[] { ClassLoader.class }); - - } catch (Exception ex) { - throw new IllegalStateException( - "Could not initialize OC4J LoadTimeWeaver because OC4J API classes are not available", ex); - } - - this.classLoader = classLoader; - } - - public void addTransformer(ClassFileTransformer transformer) { - Assert.notNull(transformer, "ClassFileTransformer must not be null"); - try { - OC4JClassPreprocessorAdapter adapter = new OC4JClassPreprocessorAdapter(transformer); - Object adapterInstance = Proxy.newProxyInstance(this.processorClass.getClassLoader(), - new Class[] { this.processorClass }, adapter); - this.addTransformer.invoke(null, new Object[] { this.classLoader, adapterInstance }); - } catch (InvocationTargetException ex) { - throw new IllegalStateException("OC4J addPreprocessor method threw exception", ex.getCause()); - } catch (Exception ex) { - throw new IllegalStateException("Could not invoke OC4J addPreprocessor method", ex); - } - } - - public ClassLoader getClassLoader() { - return this.classLoader; - } - - public ClassLoader getThrowawayClassLoader() { - try { - return (ClassLoader) this.copy.invoke(null, new Object[] { this.classLoader }); - } catch (InvocationTargetException ex) { - throw new IllegalStateException("OC4J copy method failed", ex.getCause()); - } catch (Exception ex) { - throw new IllegalStateException("Could not copy OC4J classloader", ex); - } - } +/* + * Copyright 2006-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.instrument.classloading.oc4j; + +import java.lang.instrument.ClassFileTransformer; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +import org.springframework.util.Assert; + +/** + * Reflective wrapper around a OC4J class loader. Used to + * encapsulate the classloader-specific methods (discovered and + * called through reflection) from the load-time weaver. + * + * @author Costin Leau + */ +class OC4JClassLoaderAdapter { + + private static final String CL_UTILS = "oracle.classloader.util.ClassLoaderUtilities"; + private static final String PREPROCESS_UTILS = "oracle.classloader.util.ClassPreprocessor"; + + private final ClassLoader classLoader; + private final Class<?> processorClass; + private final Method addTransformer; + private final Method copy; + + public OC4JClassLoaderAdapter(ClassLoader classLoader) { + try { + // Since OC4J 10.1.3's PolicyClassLoader is going to be removed, + // we rely on the ClassLoaderUtilities API instead. + Class<?> utilClass = classLoader.loadClass(CL_UTILS); + this.processorClass = classLoader.loadClass(PREPROCESS_UTILS); + + this.addTransformer = utilClass.getMethod("addPreprocessor", new Class[] { ClassLoader.class, + this.processorClass }); + this.copy = utilClass.getMethod("copy", new Class[] { ClassLoader.class }); + + } catch (Exception ex) { + throw new IllegalStateException( + "Could not initialize OC4J LoadTimeWeaver because OC4J API classes are not available", ex); + } + + this.classLoader = classLoader; + } + + public void addTransformer(ClassFileTransformer transformer) { + Assert.notNull(transformer, "ClassFileTransformer must not be null"); + try { + OC4JClassPreprocessorAdapter adapter = new OC4JClassPreprocessorAdapter(transformer); + Object adapterInstance = Proxy.newProxyInstance(this.processorClass.getClassLoader(), + new Class[] { this.processorClass }, adapter); + this.addTransformer.invoke(null, new Object[] { this.classLoader, adapterInstance }); + } catch (InvocationTargetException ex) { + throw new IllegalStateException("OC4J addPreprocessor method threw exception", ex.getCause()); + } catch (Exception ex) { + throw new IllegalStateException("Could not invoke OC4J addPreprocessor method", ex); + } + } + + public ClassLoader getClassLoader() { + return this.classLoader; + } + + public ClassLoader getThrowawayClassLoader() { + try { + return (ClassLoader) this.copy.invoke(null, new Object[] { this.classLoader }); + } catch (InvocationTargetException ex) { + throw new IllegalStateException("OC4J copy method failed", ex.getCause()); + } catch (Exception ex) { + throw new IllegalStateException("Could not copy OC4J classloader", ex); + } + } } \ No newline at end of file diff --git a/org.springframework.context/src/main/java/org/springframework/instrument/classloading/oc4j/OC4JClassPreprocessorAdapter.java b/org.springframework.context/src/main/java/org/springframework/instrument/classloading/oc4j/OC4JClassPreprocessorAdapter.java index 2948b691e00..540aed883e7 100644 --- a/org.springframework.context/src/main/java/org/springframework/instrument/classloading/oc4j/OC4JClassPreprocessorAdapter.java +++ b/org.springframework.context/src/main/java/org/springframework/instrument/classloading/oc4j/OC4JClassPreprocessorAdapter.java @@ -1,95 +1,95 @@ -/* - * Copyright 2006-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.instrument.classloading.oc4j; - -import java.lang.instrument.ClassFileTransformer; -import java.lang.instrument.IllegalClassFormatException; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.security.ProtectionDomain; - -/** - * Adapter that implements OC4J ClassPreProcessor interface, delegating to a - * standard JDK {@link ClassFileTransformer} underneath. - * - * <p>To avoid compile time checks again the vendor API, a dynamic proxy is - * being used. - * - * @author Costin Leau - */ -class OC4JClassPreprocessorAdapter implements InvocationHandler { - - private final ClassFileTransformer transformer; - - /** - * Creates a new {@link OC4JClassPreprocessorAdapter}. - * @param transformer the {@link ClassFileTransformer} to be adapted (must - * not be <code>null</code>) - */ - public OC4JClassPreprocessorAdapter(ClassFileTransformer transformer) { - this.transformer = transformer; - } - - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - String name = method.getName(); - - if ("equals".equals(name)) { - return (Boolean.valueOf(proxy == args[0])); - } else if ("hashCode".equals(name)) { - return hashCode(); - } else if ("toString".equals(name)) { - return toString(); - } else if ("initialize".equals(name)) { - initialize(proxy, (ClassLoader) args[0]); - return null; - } else if ("processClass".equals(name)) { - return processClass((String) args[0], (byte[]) args[1], (Integer) args[2], (Integer) args[3], - (ProtectionDomain) args[4], (ClassLoader) args[5]); - } else { - throw new IllegalArgumentException("Unknown method: " + method); - } - } - - // maps to oracle.classloader.util.ClassPreprocessor#initialize - // the proxy is passed since it implements the Oracle interface which - // is asked as a return type - public Object initialize(Object proxy, ClassLoader loader) { - return proxy; - } - - public byte[] processClass(String className, byte origClassBytes[], int offset, int length, ProtectionDomain pd, - ClassLoader loader) { - try { - byte[] tempArray = new byte[length]; - System.arraycopy(origClassBytes, offset, tempArray, 0, length); - - // NB: OC4J passes className as "." without class while the - // transformer expects a VM, "/" format - byte[] result = this.transformer.transform(loader, className.replace('.', '/'), null, pd, tempArray); - return (result != null ? result : origClassBytes); - } catch (IllegalClassFormatException ex) { - throw new IllegalStateException("Cannot transform because of illegal class format", ex); - } - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(getClass().getName()); - builder.append(" for transformer: "); - builder.append(this.transformer); - return builder.toString(); - } +/* + * Copyright 2006-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.instrument.classloading.oc4j; + +import java.lang.instrument.ClassFileTransformer; +import java.lang.instrument.IllegalClassFormatException; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.security.ProtectionDomain; + +/** + * Adapter that implements OC4J ClassPreProcessor interface, delegating to a + * standard JDK {@link ClassFileTransformer} underneath. + * + * <p>To avoid compile time checks again the vendor API, a dynamic proxy is + * being used. + * + * @author Costin Leau + */ +class OC4JClassPreprocessorAdapter implements InvocationHandler { + + private final ClassFileTransformer transformer; + + /** + * Creates a new {@link OC4JClassPreprocessorAdapter}. + * @param transformer the {@link ClassFileTransformer} to be adapted (must + * not be <code>null</code>) + */ + public OC4JClassPreprocessorAdapter(ClassFileTransformer transformer) { + this.transformer = transformer; + } + + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + String name = method.getName(); + + if ("equals".equals(name)) { + return (Boolean.valueOf(proxy == args[0])); + } else if ("hashCode".equals(name)) { + return hashCode(); + } else if ("toString".equals(name)) { + return toString(); + } else if ("initialize".equals(name)) { + initialize(proxy, (ClassLoader) args[0]); + return null; + } else if ("processClass".equals(name)) { + return processClass((String) args[0], (byte[]) args[1], (Integer) args[2], (Integer) args[3], + (ProtectionDomain) args[4], (ClassLoader) args[5]); + } else { + throw new IllegalArgumentException("Unknown method: " + method); + } + } + + // maps to oracle.classloader.util.ClassPreprocessor#initialize + // the proxy is passed since it implements the Oracle interface which + // is asked as a return type + public Object initialize(Object proxy, ClassLoader loader) { + return proxy; + } + + public byte[] processClass(String className, byte origClassBytes[], int offset, int length, ProtectionDomain pd, + ClassLoader loader) { + try { + byte[] tempArray = new byte[length]; + System.arraycopy(origClassBytes, offset, tempArray, 0, length); + + // NB: OC4J passes className as "." without class while the + // transformer expects a VM, "/" format + byte[] result = this.transformer.transform(loader, className.replace('.', '/'), null, pd, tempArray); + return (result != null ? result : origClassBytes); + } catch (IllegalClassFormatException ex) { + throw new IllegalStateException("Cannot transform because of illegal class format", ex); + } + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(getClass().getName()); + builder.append(" for transformer: "); + builder.append(this.transformer); + return builder.toString(); + } } \ No newline at end of file diff --git a/org.springframework.context/src/main/java/org/springframework/instrument/classloading/websphere/WebSphereClassLoaderAdapter.java b/org.springframework.context/src/main/java/org/springframework/instrument/classloading/websphere/WebSphereClassLoaderAdapter.java index cc0a051e435..2e0fa5cf042 100644 --- a/org.springframework.context/src/main/java/org/springframework/instrument/classloading/websphere/WebSphereClassLoaderAdapter.java +++ b/org.springframework.context/src/main/java/org/springframework/instrument/classloading/websphere/WebSphereClassLoaderAdapter.java @@ -1,111 +1,111 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.instrument.classloading.websphere; - -import java.lang.instrument.ClassFileTransformer; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.util.List; - -import org.springframework.util.Assert; - -/** - * - * Reflective wrapper around a WebSphere 7 class loader. Used to - * encapsulate the classloader-specific methods (discovered and - * called through reflection) from the load-time weaver. - * - * @author Costin Leau - * @since 3.1 - */ -class WebSphereClassLoaderAdapter { - - private static final String COMPOUND_CLASS_LOADER_NAME = "com.ibm.ws.classloader.CompoundClassLoader"; - private static final String CLASS_PRE_PROCESSOR_NAME = "com.ibm.websphere.classloader.ClassLoaderInstancePreDefinePlugin"; - private static final String PLUGINS_FIELD = "preDefinePlugins"; - - private ClassLoader classLoader; - private Class<?> wsPreProcessorClass; - private Method addPreDefinePlugin; - private Constructor<? extends ClassLoader> cloneConstructor; - private Field transformerList; - - public WebSphereClassLoaderAdapter(ClassLoader classLoader) { - Class<?> wsCompoundClassLoaderClass = null; - try { - wsCompoundClassLoaderClass = classLoader.loadClass(COMPOUND_CLASS_LOADER_NAME); - cloneConstructor = classLoader.getClass().getDeclaredConstructor(wsCompoundClassLoaderClass); - cloneConstructor.setAccessible(true); - - wsPreProcessorClass = classLoader.loadClass(CLASS_PRE_PROCESSOR_NAME); - addPreDefinePlugin = classLoader.getClass().getMethod("addPreDefinePlugin", wsPreProcessorClass); - transformerList = wsCompoundClassLoaderClass.getDeclaredField(PLUGINS_FIELD); - transformerList.setAccessible(true); - } - catch (Exception ex) { - throw new IllegalStateException( - "Could not initialize WebSphere LoadTimeWeaver because WebSphere 7 API classes are not available", - ex); - } - Assert.isInstanceOf(wsCompoundClassLoaderClass, classLoader, - "ClassLoader must be instance of [" + COMPOUND_CLASS_LOADER_NAME + "]"); - this.classLoader = classLoader; - } - - public ClassLoader getClassLoader() { - return this.classLoader; - } - - public void addTransformer(ClassFileTransformer transformer) { - Assert.notNull(transformer, "ClassFileTransformer must not be null"); - try { - InvocationHandler adapter = new WebSphereClassPreDefinePlugin(transformer); - Object adapterInstance = Proxy.newProxyInstance(this.wsPreProcessorClass.getClassLoader(), - new Class[] { this.wsPreProcessorClass }, adapter); - this.addPreDefinePlugin.invoke(this.classLoader, adapterInstance); - - } - catch (InvocationTargetException ex) { - throw new IllegalStateException("WebSphere addPreDefinePlugin method threw exception", ex.getCause()); - } - catch (Exception ex) { - throw new IllegalStateException("Could not invoke WebSphere addPreDefinePlugin method", ex); - } - } - - @SuppressWarnings("unchecked") - public ClassLoader getThrowawayClassLoader() { - try { - ClassLoader loader = (ClassLoader) cloneConstructor.newInstance(getClassLoader()); - // clear out the transformers (copied as well) - List list = (List) transformerList.get(loader); - list.clear(); - return loader; - } - catch (InvocationTargetException ex) { - throw new IllegalStateException("WebSphere CompoundClassLoader constructor failed", ex.getCause()); - } - catch (Exception ex) { - throw new IllegalStateException("Could not construct WebSphere CompoundClassLoader", ex); - } - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.instrument.classloading.websphere; + +import java.lang.instrument.ClassFileTransformer; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.List; + +import org.springframework.util.Assert; + +/** + * + * Reflective wrapper around a WebSphere 7 class loader. Used to + * encapsulate the classloader-specific methods (discovered and + * called through reflection) from the load-time weaver. + * + * @author Costin Leau + * @since 3.1 + */ +class WebSphereClassLoaderAdapter { + + private static final String COMPOUND_CLASS_LOADER_NAME = "com.ibm.ws.classloader.CompoundClassLoader"; + private static final String CLASS_PRE_PROCESSOR_NAME = "com.ibm.websphere.classloader.ClassLoaderInstancePreDefinePlugin"; + private static final String PLUGINS_FIELD = "preDefinePlugins"; + + private ClassLoader classLoader; + private Class<?> wsPreProcessorClass; + private Method addPreDefinePlugin; + private Constructor<? extends ClassLoader> cloneConstructor; + private Field transformerList; + + public WebSphereClassLoaderAdapter(ClassLoader classLoader) { + Class<?> wsCompoundClassLoaderClass = null; + try { + wsCompoundClassLoaderClass = classLoader.loadClass(COMPOUND_CLASS_LOADER_NAME); + cloneConstructor = classLoader.getClass().getDeclaredConstructor(wsCompoundClassLoaderClass); + cloneConstructor.setAccessible(true); + + wsPreProcessorClass = classLoader.loadClass(CLASS_PRE_PROCESSOR_NAME); + addPreDefinePlugin = classLoader.getClass().getMethod("addPreDefinePlugin", wsPreProcessorClass); + transformerList = wsCompoundClassLoaderClass.getDeclaredField(PLUGINS_FIELD); + transformerList.setAccessible(true); + } + catch (Exception ex) { + throw new IllegalStateException( + "Could not initialize WebSphere LoadTimeWeaver because WebSphere 7 API classes are not available", + ex); + } + Assert.isInstanceOf(wsCompoundClassLoaderClass, classLoader, + "ClassLoader must be instance of [" + COMPOUND_CLASS_LOADER_NAME + "]"); + this.classLoader = classLoader; + } + + public ClassLoader getClassLoader() { + return this.classLoader; + } + + public void addTransformer(ClassFileTransformer transformer) { + Assert.notNull(transformer, "ClassFileTransformer must not be null"); + try { + InvocationHandler adapter = new WebSphereClassPreDefinePlugin(transformer); + Object adapterInstance = Proxy.newProxyInstance(this.wsPreProcessorClass.getClassLoader(), + new Class[] { this.wsPreProcessorClass }, adapter); + this.addPreDefinePlugin.invoke(this.classLoader, adapterInstance); + + } + catch (InvocationTargetException ex) { + throw new IllegalStateException("WebSphere addPreDefinePlugin method threw exception", ex.getCause()); + } + catch (Exception ex) { + throw new IllegalStateException("Could not invoke WebSphere addPreDefinePlugin method", ex); + } + } + + @SuppressWarnings("unchecked") + public ClassLoader getThrowawayClassLoader() { + try { + ClassLoader loader = (ClassLoader) cloneConstructor.newInstance(getClassLoader()); + // clear out the transformers (copied as well) + List list = (List) transformerList.get(loader); + list.clear(); + return loader; + } + catch (InvocationTargetException ex) { + throw new IllegalStateException("WebSphere CompoundClassLoader constructor failed", ex.getCause()); + } + catch (Exception ex) { + throw new IllegalStateException("Could not construct WebSphere CompoundClassLoader", ex); + } + } + +} diff --git a/org.springframework.context/src/main/java/org/springframework/instrument/classloading/websphere/WebSphereClassPreDefinePlugin.java b/org.springframework.context/src/main/java/org/springframework/instrument/classloading/websphere/WebSphereClassPreDefinePlugin.java index b4d70120e64..748ba182a45 100644 --- a/org.springframework.context/src/main/java/org/springframework/instrument/classloading/websphere/WebSphereClassPreDefinePlugin.java +++ b/org.springframework.context/src/main/java/org/springframework/instrument/classloading/websphere/WebSphereClassPreDefinePlugin.java @@ -1,100 +1,100 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.instrument.classloading.websphere; - -import java.lang.instrument.ClassFileTransformer; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.security.CodeSource; - -import org.springframework.util.FileCopyUtils; - -/** - * Adapter that implements WebSphere 7.0 ClassPreProcessPlugin interface, - * delegating to a standard JDK {@link ClassFileTransformer} underneath. - * - * <p>To avoid compile time checks again the vendor API, a dynamic proxy is - * being used. - * - * @author Costin Leau - * @since 3.1 - */ -class WebSphereClassPreDefinePlugin implements InvocationHandler { - - private final ClassFileTransformer transformer; - - - /** - * Create a new {@link WebSphereClassPreDefinePlugin}. - * @param transformer the {@link ClassFileTransformer} to be adapted - * (must not be <code>null</code>) - */ - public WebSphereClassPreDefinePlugin(ClassFileTransformer transformer) { - this.transformer = transformer; - ClassLoader classLoader = transformer.getClass().getClassLoader(); - - // first force the full class loading of the weaver by invoking transformation on a dummy class - try { - String dummyClass = Dummy.class.getName().replace('.', '/'); - byte[] bytes = FileCopyUtils.copyToByteArray(classLoader.getResourceAsStream(dummyClass + ".class")); - transformer.transform(classLoader, dummyClass, null, null, bytes); - } - catch (Throwable ex) { - throw new IllegalArgumentException("Cannot load transformer", ex); - } - } - - - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - String name = method.getName(); - if ("equals".equals(name)) { - return (proxy == args[0]); - } - else if ("hashCode".equals(name)) { - return hashCode(); - } - else if ("toString".equals(name)) { - return toString(); - } - else if ("transformClass".equals(name)) { - return transform((String) args[0], (byte[]) args[1], (CodeSource) args[2], (ClassLoader) args[3]); - } - else { - throw new IllegalArgumentException("Unknown method: " + method); - } - } - - protected byte[] transform(String className, byte[] classfileBuffer, CodeSource codeSource, ClassLoader classLoader) - throws Exception { - - // NB: WebSphere passes className as "." without class while the transformer expects a VM, "/" format - byte[] result = transformer.transform(classLoader, className.replace('.', '/'), null, null, classfileBuffer); - return (result != null ? result : classfileBuffer); - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(getClass().getName()); - builder.append(" for transformer: "); - builder.append(this.transformer); - return builder.toString(); - } - - - private static class Dummy { - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.instrument.classloading.websphere; + +import java.lang.instrument.ClassFileTransformer; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.security.CodeSource; + +import org.springframework.util.FileCopyUtils; + +/** + * Adapter that implements WebSphere 7.0 ClassPreProcessPlugin interface, + * delegating to a standard JDK {@link ClassFileTransformer} underneath. + * + * <p>To avoid compile time checks again the vendor API, a dynamic proxy is + * being used. + * + * @author Costin Leau + * @since 3.1 + */ +class WebSphereClassPreDefinePlugin implements InvocationHandler { + + private final ClassFileTransformer transformer; + + + /** + * Create a new {@link WebSphereClassPreDefinePlugin}. + * @param transformer the {@link ClassFileTransformer} to be adapted + * (must not be <code>null</code>) + */ + public WebSphereClassPreDefinePlugin(ClassFileTransformer transformer) { + this.transformer = transformer; + ClassLoader classLoader = transformer.getClass().getClassLoader(); + + // first force the full class loading of the weaver by invoking transformation on a dummy class + try { + String dummyClass = Dummy.class.getName().replace('.', '/'); + byte[] bytes = FileCopyUtils.copyToByteArray(classLoader.getResourceAsStream(dummyClass + ".class")); + transformer.transform(classLoader, dummyClass, null, null, bytes); + } + catch (Throwable ex) { + throw new IllegalArgumentException("Cannot load transformer", ex); + } + } + + + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + String name = method.getName(); + if ("equals".equals(name)) { + return (proxy == args[0]); + } + else if ("hashCode".equals(name)) { + return hashCode(); + } + else if ("toString".equals(name)) { + return toString(); + } + else if ("transformClass".equals(name)) { + return transform((String) args[0], (byte[]) args[1], (CodeSource) args[2], (ClassLoader) args[3]); + } + else { + throw new IllegalArgumentException("Unknown method: " + method); + } + } + + protected byte[] transform(String className, byte[] classfileBuffer, CodeSource codeSource, ClassLoader classLoader) + throws Exception { + + // NB: WebSphere passes className as "." without class while the transformer expects a VM, "/" format + byte[] result = transformer.transform(classLoader, className.replace('.', '/'), null, null, classfileBuffer); + return (result != null ? result : classfileBuffer); + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(getClass().getName()); + builder.append(" for transformer: "); + builder.append(this.transformer); + return builder.toString(); + } + + + private static class Dummy { + } + +} diff --git a/org.springframework.context/src/main/java/org/springframework/instrument/classloading/websphere/WebSphereLoadTimeWeaver.java b/org.springframework.context/src/main/java/org/springframework/instrument/classloading/websphere/WebSphereLoadTimeWeaver.java index 724a1db6b11..1344bef8aa3 100644 --- a/org.springframework.context/src/main/java/org/springframework/instrument/classloading/websphere/WebSphereLoadTimeWeaver.java +++ b/org.springframework.context/src/main/java/org/springframework/instrument/classloading/websphere/WebSphereLoadTimeWeaver.java @@ -1,70 +1,70 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.instrument.classloading.websphere; - -import java.lang.instrument.ClassFileTransformer; - -import org.springframework.instrument.classloading.LoadTimeWeaver; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; - -/** - * {@link LoadTimeWeaver} implementation for WebSphere's instrumentable ClassLoader. - * Compatible with WebSphere 7 as well as 8. - * - * @author Costin Leau - * @since 3.1 - */ -public class WebSphereLoadTimeWeaver implements LoadTimeWeaver { - - private final WebSphereClassLoaderAdapter classLoader; - - - /** - * Create a new instance of the {@link WebSphereLoadTimeWeaver} class using - * the default {@link ClassLoader class loader}. - * @see org.springframework.util.ClassUtils#getDefaultClassLoader() - */ - public WebSphereLoadTimeWeaver() { - this(ClassUtils.getDefaultClassLoader()); - } - - /** - * Create a new instance of the {@link WebSphereLoadTimeWeaver} class using - * the supplied {@link ClassLoader}. - * @param classLoader the <code>ClassLoader</code> to delegate to for weaving - * (must not be <code>null</code>) - */ - public WebSphereLoadTimeWeaver(ClassLoader classLoader) { - Assert.notNull(classLoader, "ClassLoader must not be null"); - this.classLoader = new WebSphereClassLoaderAdapter(classLoader); - } - - - public void addTransformer(ClassFileTransformer transformer) { - this.classLoader.addTransformer(transformer); - } - - public ClassLoader getInstrumentableClassLoader() { - return this.classLoader.getClassLoader(); - } - - public ClassLoader getThrowawayClassLoader() { - return this.classLoader.getThrowawayClassLoader(); - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.instrument.classloading.websphere; + +import java.lang.instrument.ClassFileTransformer; + +import org.springframework.instrument.classloading.LoadTimeWeaver; +import org.springframework.util.Assert; +import org.springframework.util.ClassUtils; + +/** + * {@link LoadTimeWeaver} implementation for WebSphere's instrumentable ClassLoader. + * Compatible with WebSphere 7 as well as 8. + * + * @author Costin Leau + * @since 3.1 + */ +public class WebSphereLoadTimeWeaver implements LoadTimeWeaver { + + private final WebSphereClassLoaderAdapter classLoader; + + + /** + * Create a new instance of the {@link WebSphereLoadTimeWeaver} class using + * the default {@link ClassLoader class loader}. + * @see org.springframework.util.ClassUtils#getDefaultClassLoader() + */ + public WebSphereLoadTimeWeaver() { + this(ClassUtils.getDefaultClassLoader()); + } + + /** + * Create a new instance of the {@link WebSphereLoadTimeWeaver} class using + * the supplied {@link ClassLoader}. + * @param classLoader the <code>ClassLoader</code> to delegate to for weaving + * (must not be <code>null</code>) + */ + public WebSphereLoadTimeWeaver(ClassLoader classLoader) { + Assert.notNull(classLoader, "ClassLoader must not be null"); + this.classLoader = new WebSphereClassLoaderAdapter(classLoader); + } + + + public void addTransformer(ClassFileTransformer transformer) { + this.classLoader.addTransformer(transformer); + } + + public ClassLoader getInstrumentableClassLoader() { + return this.classLoader.getClassLoader(); + } + + public ClassLoader getThrowawayClassLoader() { + return this.classLoader.getThrowawayClassLoader(); + } + +} diff --git a/org.springframework.context/src/main/java/org/springframework/instrument/classloading/websphere/package-info.java b/org.springframework.context/src/main/java/org/springframework/instrument/classloading/websphere/package-info.java index 2f65915eb2c..5b5a27519a8 100644 --- a/org.springframework.context/src/main/java/org/springframework/instrument/classloading/websphere/package-info.java +++ b/org.springframework.context/src/main/java/org/springframework/instrument/classloading/websphere/package-info.java @@ -1,8 +1,8 @@ - -/** - * - * Support for class instrumentation on IBM WebSphere Application Server 7. - * - */ -package org.springframework.instrument.classloading.websphere; - + +/** + * + * Support for class instrumentation on IBM WebSphere Application Server 7. + * + */ +package org.springframework.instrument.classloading.websphere; + diff --git a/org.springframework.context/src/main/java/org/springframework/jndi/JndiLocatorDelegate.java b/org.springframework.context/src/main/java/org/springframework/jndi/JndiLocatorDelegate.java index fd2687e0339..9b4789a724b 100644 --- a/org.springframework.context/src/main/java/org/springframework/jndi/JndiLocatorDelegate.java +++ b/org.springframework.context/src/main/java/org/springframework/jndi/JndiLocatorDelegate.java @@ -1,69 +1,69 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jndi; - -import javax.naming.InitialContext; -import javax.naming.NamingException; - -/** - * {@link JndiLocatorSupport} subclass with public lookup methods, - * for convenient use as a delegate. - * - * @author Juergen Hoeller - * @since 3.0.1 - */ -public class JndiLocatorDelegate extends JndiLocatorSupport { - - @Override - public Object lookup(String jndiName) throws NamingException { - return super.lookup(jndiName); - } - - @Override - public <T> T lookup(String jndiName, Class<T> requiredType) throws NamingException { - return super.lookup(jndiName, requiredType); - } - - - /** - * Configure a {@code JndiLocatorDelegate} with its "resourceRef" property set to - * <code>true</code>, meaning that all names will be prefixed with "java:comp/env/". - * @see #setResourceRef - */ - public static JndiLocatorDelegate createDefaultResourceRefLocator() { - JndiLocatorDelegate jndiLocator = new JndiLocatorDelegate(); - jndiLocator.setResourceRef(true); - return jndiLocator; - } - - /** - * Check whether a default JNDI environment, as in a J2EE environment, - * is available on this JVM. - * @return <code>true</code> if a default InitialContext can be used, - * <code>false</code> if not - */ - public static boolean isDefaultJndiEnvironmentAvailable() { - try { - new InitialContext(); - return true; - } - catch (Throwable ex) { - return false; - } - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.jndi; + +import javax.naming.InitialContext; +import javax.naming.NamingException; + +/** + * {@link JndiLocatorSupport} subclass with public lookup methods, + * for convenient use as a delegate. + * + * @author Juergen Hoeller + * @since 3.0.1 + */ +public class JndiLocatorDelegate extends JndiLocatorSupport { + + @Override + public Object lookup(String jndiName) throws NamingException { + return super.lookup(jndiName); + } + + @Override + public <T> T lookup(String jndiName, Class<T> requiredType) throws NamingException { + return super.lookup(jndiName, requiredType); + } + + + /** + * Configure a {@code JndiLocatorDelegate} with its "resourceRef" property set to + * <code>true</code>, meaning that all names will be prefixed with "java:comp/env/". + * @see #setResourceRef + */ + public static JndiLocatorDelegate createDefaultResourceRefLocator() { + JndiLocatorDelegate jndiLocator = new JndiLocatorDelegate(); + jndiLocator.setResourceRef(true); + return jndiLocator; + } + + /** + * Check whether a default JNDI environment, as in a J2EE environment, + * is available on this JVM. + * @return <code>true</code> if a default InitialContext can be used, + * <code>false</code> if not + */ + public static boolean isDefaultJndiEnvironmentAvailable() { + try { + new InitialContext(); + return true; + } + catch (Throwable ex) { + return false; + } + } + +} diff --git a/org.springframework.context/src/main/java/org/springframework/scheduling/TaskScheduler.java b/org.springframework.context/src/main/java/org/springframework/scheduling/TaskScheduler.java index 5b0dcaf2f52..6546c2160e1 100644 --- a/org.springframework.context/src/main/java/org/springframework/scheduling/TaskScheduler.java +++ b/org.springframework.context/src/main/java/org/springframework/scheduling/TaskScheduler.java @@ -1,139 +1,139 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.scheduling; - -import java.util.Date; -import java.util.concurrent.ScheduledFuture; - -/** - * Task scheduler interface that abstracts the scheduling of - * {@link Runnable Runnables} based on different kinds of triggers. - * - * <p>This interface is separate from {@link SchedulingTaskExecutor} since it - * usually represents for a different kind of backend, i.e. a thread pool with - * different characteristics and capabilities. Implementations may implement - * both interfaces if they can handle both kinds of execution characteristics. - * - * <p>The 'default' implementation is - * {@link org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler}, - * wrapping a native {@link java.util.concurrent.ScheduledExecutorService} - * and adding extended trigger capabilities. - * - * <p>This interface is roughly equivalent to a JSR-236 - * <code>ManagedScheduledExecutorService</code> as supported in Java EE 6 - * environments. However, at the time of the Spring 3.0 release, the - * JSR-236 interfaces have not been released in official form yet. - * - * @author Juergen Hoeller - * @since 3.0 - * @see org.springframework.core.task.TaskExecutor - * @see java.util.concurrent.ScheduledExecutorService - * @see org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler - */ -public interface TaskScheduler { - - /** - * Schedule the given {@link Runnable}, invoking it whenever the trigger - * indicates a next execution time. - * <p>Execution will end once the scheduler shuts down or the returned - * {@link ScheduledFuture} gets cancelled. - * @param task the Runnable to execute whenever the trigger fires - * @param trigger an implementation of the {@link Trigger} interface, - * e.g. a {@link org.springframework.scheduling.support.CronTrigger} object - * wrapping a cron expression - * @return a {@link ScheduledFuture} representing pending completion of the task, - * or <code>null</code> if the given Trigger object never fires (i.e. returns - * <code>null</code> from {@link Trigger#nextExecutionTime}) - * @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted - * for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress) - * @see org.springframework.scheduling.support.CronTrigger - */ - ScheduledFuture schedule(Runnable task, Trigger trigger); - - /** - * Schedule the given {@link Runnable}, invoking it at the specified execution time. - * <p>Execution will end once the scheduler shuts down or the returned - * {@link ScheduledFuture} gets cancelled. - * @param task the Runnable to execute whenever the trigger fires - * @param startTime the desired execution time for the task - * (if this is in the past, the task will be executed immediately, i.e. as soon as possible) - * @return a {@link ScheduledFuture} representing pending completion of the task - * @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted - * for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress) - */ - ScheduledFuture schedule(Runnable task, Date startTime); - - /** - * Schedule the given {@link Runnable}, invoking it at the specified execution time - * and subsequently with the given period. - * <p>Execution will end once the scheduler shuts down or the returned - * {@link ScheduledFuture} gets cancelled. - * @param task the Runnable to execute whenever the trigger fires - * @param startTime the desired first execution time for the task - * (if this is in the past, the task will be executed immediately, i.e. as soon as possible) - * @param period the interval between successive executions of the task (in milliseconds) - * @return a {@link ScheduledFuture} representing pending completion of the task - * @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted - * for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress) - */ - ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period); - - /** - * Schedule the given {@link Runnable}, starting as soon as possible and - * invoking it with the given period. - * <p>Execution will end once the scheduler shuts down or the returned - * {@link ScheduledFuture} gets cancelled. - * @param task the Runnable to execute whenever the trigger fires - * @param period the interval between successive executions of the task (in milliseconds) - * @return a {@link ScheduledFuture} representing pending completion of the task - * @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted - * for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress) - */ - ScheduledFuture scheduleAtFixedRate(Runnable task, long period); - - /** - * Schedule the given {@link Runnable}, invoking it at the specified execution time - * and subsequently with the given delay between the completion of one execution - * and the start of the next. - * <p>Execution will end once the scheduler shuts down or the returned - * {@link ScheduledFuture} gets cancelled. - * @param task the Runnable to execute whenever the trigger fires - * @param startTime the desired first execution time for the task - * (if this is in the past, the task will be executed immediately, i.e. as soon as possible) - * @param delay the delay between the completion of one execution and the start - * of the next (in milliseconds) - * @return a {@link ScheduledFuture} representing pending completion of the task - * @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted - * for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress) - */ - ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay); - - /** - * Schedule the given {@link Runnable}, starting as soon as possible and - * invoking it with the given delay between the completion of one execution - * and the start of the next. - * <p>Execution will end once the scheduler shuts down or the returned - * {@link ScheduledFuture} gets cancelled. - * @param task the Runnable to execute whenever the trigger fires - * @param delay the interval between successive executions of the task (in milliseconds) - * @return a {@link ScheduledFuture} representing pending completion of the task - * @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted - * for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress) - */ - ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay); - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.scheduling; + +import java.util.Date; +import java.util.concurrent.ScheduledFuture; + +/** + * Task scheduler interface that abstracts the scheduling of + * {@link Runnable Runnables} based on different kinds of triggers. + * + * <p>This interface is separate from {@link SchedulingTaskExecutor} since it + * usually represents for a different kind of backend, i.e. a thread pool with + * different characteristics and capabilities. Implementations may implement + * both interfaces if they can handle both kinds of execution characteristics. + * + * <p>The 'default' implementation is + * {@link org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler}, + * wrapping a native {@link java.util.concurrent.ScheduledExecutorService} + * and adding extended trigger capabilities. + * + * <p>This interface is roughly equivalent to a JSR-236 + * <code>ManagedScheduledExecutorService</code> as supported in Java EE 6 + * environments. However, at the time of the Spring 3.0 release, the + * JSR-236 interfaces have not been released in official form yet. + * + * @author Juergen Hoeller + * @since 3.0 + * @see org.springframework.core.task.TaskExecutor + * @see java.util.concurrent.ScheduledExecutorService + * @see org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler + */ +public interface TaskScheduler { + + /** + * Schedule the given {@link Runnable}, invoking it whenever the trigger + * indicates a next execution time. + * <p>Execution will end once the scheduler shuts down or the returned + * {@link ScheduledFuture} gets cancelled. + * @param task the Runnable to execute whenever the trigger fires + * @param trigger an implementation of the {@link Trigger} interface, + * e.g. a {@link org.springframework.scheduling.support.CronTrigger} object + * wrapping a cron expression + * @return a {@link ScheduledFuture} representing pending completion of the task, + * or <code>null</code> if the given Trigger object never fires (i.e. returns + * <code>null</code> from {@link Trigger#nextExecutionTime}) + * @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted + * for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress) + * @see org.springframework.scheduling.support.CronTrigger + */ + ScheduledFuture schedule(Runnable task, Trigger trigger); + + /** + * Schedule the given {@link Runnable}, invoking it at the specified execution time. + * <p>Execution will end once the scheduler shuts down or the returned + * {@link ScheduledFuture} gets cancelled. + * @param task the Runnable to execute whenever the trigger fires + * @param startTime the desired execution time for the task + * (if this is in the past, the task will be executed immediately, i.e. as soon as possible) + * @return a {@link ScheduledFuture} representing pending completion of the task + * @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted + * for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress) + */ + ScheduledFuture schedule(Runnable task, Date startTime); + + /** + * Schedule the given {@link Runnable}, invoking it at the specified execution time + * and subsequently with the given period. + * <p>Execution will end once the scheduler shuts down or the returned + * {@link ScheduledFuture} gets cancelled. + * @param task the Runnable to execute whenever the trigger fires + * @param startTime the desired first execution time for the task + * (if this is in the past, the task will be executed immediately, i.e. as soon as possible) + * @param period the interval between successive executions of the task (in milliseconds) + * @return a {@link ScheduledFuture} representing pending completion of the task + * @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted + * for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress) + */ + ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period); + + /** + * Schedule the given {@link Runnable}, starting as soon as possible and + * invoking it with the given period. + * <p>Execution will end once the scheduler shuts down or the returned + * {@link ScheduledFuture} gets cancelled. + * @param task the Runnable to execute whenever the trigger fires + * @param period the interval between successive executions of the task (in milliseconds) + * @return a {@link ScheduledFuture} representing pending completion of the task + * @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted + * for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress) + */ + ScheduledFuture scheduleAtFixedRate(Runnable task, long period); + + /** + * Schedule the given {@link Runnable}, invoking it at the specified execution time + * and subsequently with the given delay between the completion of one execution + * and the start of the next. + * <p>Execution will end once the scheduler shuts down or the returned + * {@link ScheduledFuture} gets cancelled. + * @param task the Runnable to execute whenever the trigger fires + * @param startTime the desired first execution time for the task + * (if this is in the past, the task will be executed immediately, i.e. as soon as possible) + * @param delay the delay between the completion of one execution and the start + * of the next (in milliseconds) + * @return a {@link ScheduledFuture} representing pending completion of the task + * @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted + * for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress) + */ + ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay); + + /** + * Schedule the given {@link Runnable}, starting as soon as possible and + * invoking it with the given delay between the completion of one execution + * and the start of the next. + * <p>Execution will end once the scheduler shuts down or the returned + * {@link ScheduledFuture} gets cancelled. + * @param task the Runnable to execute whenever the trigger fires + * @param delay the interval between successive executions of the task (in milliseconds) + * @return a {@link ScheduledFuture} representing pending completion of the task + * @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted + * for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress) + */ + ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay); + +} diff --git a/org.springframework.context/src/main/java/org/springframework/scheduling/Trigger.java b/org.springframework.context/src/main/java/org/springframework/scheduling/Trigger.java index 9849d4b932c..1f17217ee9c 100644 --- a/org.springframework.context/src/main/java/org/springframework/scheduling/Trigger.java +++ b/org.springframework.context/src/main/java/org/springframework/scheduling/Trigger.java @@ -1,41 +1,41 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.scheduling; - -import java.util.Date; - -/** - * Common interface for trigger objects that determine the next execution time - * of a task that they get associated with. - * - * @author Juergen Hoeller - * @since 3.0 - * @see TaskScheduler#schedule(Runnable, Trigger) - * @see org.springframework.scheduling.support.CronTrigger - */ -public interface Trigger { - - /** - * Determine the next execution time according to the given trigger context. - * @param triggerContext context object encapsulating last execution times - * and last completion time - * @return the next execution time as defined by the trigger, - * or <code>null</code> if the trigger won't fire anymore - */ - Date nextExecutionTime(TriggerContext triggerContext); - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.scheduling; + +import java.util.Date; + +/** + * Common interface for trigger objects that determine the next execution time + * of a task that they get associated with. + * + * @author Juergen Hoeller + * @since 3.0 + * @see TaskScheduler#schedule(Runnable, Trigger) + * @see org.springframework.scheduling.support.CronTrigger + */ +public interface Trigger { + + /** + * Determine the next execution time according to the given trigger context. + * @param triggerContext context object encapsulating last execution times + * and last completion time + * @return the next execution time as defined by the trigger, + * or <code>null</code> if the trigger won't fire anymore + */ + Date nextExecutionTime(TriggerContext triggerContext); + +} diff --git a/org.springframework.context/src/main/java/org/springframework/scheduling/TriggerContext.java b/org.springframework.context/src/main/java/org/springframework/scheduling/TriggerContext.java index 3785b43784d..bd483a48e4e 100644 --- a/org.springframework.context/src/main/java/org/springframework/scheduling/TriggerContext.java +++ b/org.springframework.context/src/main/java/org/springframework/scheduling/TriggerContext.java @@ -1,48 +1,48 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.scheduling; - -import java.util.Date; - -/** - * Context object encapsulating last execution times and last completion time - * of a given task. - * - * @author Juergen Hoeller - * @since 3.0 - */ -public interface TriggerContext { - - /** - * Return the last <i>scheduled</i> execution time of the task, - * or <code>null</code> if not scheduled before. - */ - Date lastScheduledExecutionTime(); - - /** - * Return the last <i>actual</i> execution time of the task, - * or <code>null</code> if not scheduled before. - */ - Date lastActualExecutionTime(); - - /** - * Return the last completion time of the task, - * or <code>null</code> if not scheduled before. - */ - Date lastCompletionTime(); - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.scheduling; + +import java.util.Date; + +/** + * Context object encapsulating last execution times and last completion time + * of a given task. + * + * @author Juergen Hoeller + * @since 3.0 + */ +public interface TriggerContext { + + /** + * Return the last <i>scheduled</i> execution time of the task, + * or <code>null</code> if not scheduled before. + */ + Date lastScheduledExecutionTime(); + + /** + * Return the last <i>actual</i> execution time of the task, + * or <code>null</code> if not scheduled before. + */ + Date lastActualExecutionTime(); + + /** + * Return the last completion time of the task, + * or <code>null</code> if not scheduled before. + */ + Date lastCompletionTime(); + +} diff --git a/org.springframework.context/src/main/java/org/springframework/scheduling/annotation/Async.java b/org.springframework.context/src/main/java/org/springframework/scheduling/annotation/Async.java index 90276bf6386..c79f9ecd832 100644 --- a/org.springframework.context/src/main/java/org/springframework/scheduling/annotation/Async.java +++ b/org.springframework.context/src/main/java/org/springframework/scheduling/annotation/Async.java @@ -1,49 +1,49 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.scheduling.annotation; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Annotation that marks a method as a candidate for <i>asynchronous</i> execution. - * Can also be used at the type level, in which case all of the type's methods are - * considered as asynchronous. - * - * <p>In terms of target method signatures, any parameter types are supported. - * However, the return type is constrained to either <code>void</code> or - * <code>java.util.concurrent.Future</code>. In the latter case, the Future handle - * returned from the proxy will be an actual asynchronous Future that can be used - * to track the result of the asynchronous method execution. However, since the - * target method needs to implement the same signature, it will have to return - * a temporary Future handle that just passes the return value through: e.g. - * Spring's {@link AsyncResult} or EJB 3.1's <code>javax.ejb.AsyncResult</code>. - * - * @author Juergen Hoeller - * @since 3.0 - * @see org.springframework.aop.interceptor.AsyncExecutionInterceptor - * @see AsyncAnnotationAdvisor - */ -@Target({ElementType.TYPE, ElementType.METHOD}) -@Retention(RetentionPolicy.RUNTIME) -@Documented -public @interface Async { - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.scheduling.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation that marks a method as a candidate for <i>asynchronous</i> execution. + * Can also be used at the type level, in which case all of the type's methods are + * considered as asynchronous. + * + * <p>In terms of target method signatures, any parameter types are supported. + * However, the return type is constrained to either <code>void</code> or + * <code>java.util.concurrent.Future</code>. In the latter case, the Future handle + * returned from the proxy will be an actual asynchronous Future that can be used + * to track the result of the asynchronous method execution. However, since the + * target method needs to implement the same signature, it will have to return + * a temporary Future handle that just passes the return value through: e.g. + * Spring's {@link AsyncResult} or EJB 3.1's <code>javax.ejb.AsyncResult</code>. + * + * @author Juergen Hoeller + * @since 3.0 + * @see org.springframework.aop.interceptor.AsyncExecutionInterceptor + * @see AsyncAnnotationAdvisor + */ +@Target({ElementType.TYPE, ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface Async { + +} diff --git a/org.springframework.context/src/main/java/org/springframework/scheduling/annotation/AsyncResult.java b/org.springframework.context/src/main/java/org/springframework/scheduling/annotation/AsyncResult.java index f13e17cea3c..bfe91befc44 100644 --- a/org.springframework.context/src/main/java/org/springframework/scheduling/annotation/AsyncResult.java +++ b/org.springframework.context/src/main/java/org/springframework/scheduling/annotation/AsyncResult.java @@ -1,63 +1,63 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.scheduling.annotation; - -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; - -/** - * A pass-through <code>Future</code> handle that can be used for method signatures - * which are declared with a Future return type for asynchronous execution. - * - * @author Juergen Hoeller - * @since 3.0 - * @see org.springframework.scheduling.annotation.Async - */ -public class AsyncResult<V> implements Future<V> { - - private final V value; - - - /** - * Create a new AsyncResult holder. - * @param value the value to pass through - */ - public AsyncResult(V value) { - this.value = value; - } - - public boolean cancel(boolean mayInterruptIfRunning) { - return false; - } - - public boolean isCancelled() { - return false; - } - - public boolean isDone() { - return true; - } - - public V get() { - return this.value; - } - - public V get(long timeout, TimeUnit unit) { - return this.value; - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.scheduling.annotation; + +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +/** + * A pass-through <code>Future</code> handle that can be used for method signatures + * which are declared with a Future return type for asynchronous execution. + * + * @author Juergen Hoeller + * @since 3.0 + * @see org.springframework.scheduling.annotation.Async + */ +public class AsyncResult<V> implements Future<V> { + + private final V value; + + + /** + * Create a new AsyncResult holder. + * @param value the value to pass through + */ + public AsyncResult(V value) { + this.value = value; + } + + public boolean cancel(boolean mayInterruptIfRunning) { + return false; + } + + public boolean isCancelled() { + return false; + } + + public boolean isDone() { + return true; + } + + public V get() { + return this.value; + } + + public V get(long timeout, TimeUnit unit) { + return this.value; + } + +} diff --git a/org.springframework.context/src/main/java/org/springframework/scheduling/annotation/Scheduled.java b/org.springframework.context/src/main/java/org/springframework/scheduling/annotation/Scheduled.java index 87b9693acd1..ccda008fcc8 100644 --- a/org.springframework.context/src/main/java/org/springframework/scheduling/annotation/Scheduled.java +++ b/org.springframework.context/src/main/java/org/springframework/scheduling/annotation/Scheduled.java @@ -1,71 +1,71 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.scheduling.annotation; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Annotation that marks a method to be scheduled. Exactly one of the - * <code>cron</code>, <code>fixedDelay</code>, or <code>fixedRate</code> - * attributes must be provided. - * - * <p>The annotated method must expect no arguments and have a - * <code>void</code> return type. - * - * <p>Processing of {@code @Scheduled} annotations is performed by - * registering a {@link ScheduledAnnotationBeanPostProcessor}. This can be - * done manually or, more conveniently, through the {@code <task:annotation-driven/>} - * element or @{@link EnableScheduling} annotation. - * - * @author Mark Fisher - * @author Dave Syer - * @since 3.0 - * @see EnableScheduling - * @see ScheduledAnnotationBeanPostProcessor - */ -@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) -@Retention(RetentionPolicy.RUNTIME) -@Documented -public @interface Scheduled { - - /** - * A cron-like expression, extending the usual UN*X definition to include - * triggers on the second as well as minute, hour, day of month, month - * and day of week. e.g. <code>"0 * * * * MON-FRI"</code> means once - * per minute on weekdays (at the top of the minute - the 0th second). - * @return an expression that can be parsed to a cron schedule - */ - String cron() default ""; - - /** - * Execute the annotated method with a fixed period between the end - * of the last invocation and the start of the next. - * @return the delay in milliseconds - */ - long fixedDelay() default -1; - - /** - * Execute the annotated method with a fixed period between invocations. - * @return the period in milliseconds - */ - long fixedRate() default -1; - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.scheduling.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation that marks a method to be scheduled. Exactly one of the + * <code>cron</code>, <code>fixedDelay</code>, or <code>fixedRate</code> + * attributes must be provided. + * + * <p>The annotated method must expect no arguments and have a + * <code>void</code> return type. + * + * <p>Processing of {@code @Scheduled} annotations is performed by + * registering a {@link ScheduledAnnotationBeanPostProcessor}. This can be + * done manually or, more conveniently, through the {@code <task:annotation-driven/>} + * element or @{@link EnableScheduling} annotation. + * + * @author Mark Fisher + * @author Dave Syer + * @since 3.0 + * @see EnableScheduling + * @see ScheduledAnnotationBeanPostProcessor + */ +@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface Scheduled { + + /** + * A cron-like expression, extending the usual UN*X definition to include + * triggers on the second as well as minute, hour, day of month, month + * and day of week. e.g. <code>"0 * * * * MON-FRI"</code> means once + * per minute on weekdays (at the top of the minute - the 0th second). + * @return an expression that can be parsed to a cron schedule + */ + String cron() default ""; + + /** + * Execute the annotated method with a fixed period between the end + * of the last invocation and the start of the next. + * @return the delay in milliseconds + */ + long fixedDelay() default -1; + + /** + * Execute the annotated method with a fixed period between invocations. + * @return the period in milliseconds + */ + long fixedRate() default -1; + +} diff --git a/org.springframework.context/src/main/java/org/springframework/scheduling/concurrent/ConcurrentTaskScheduler.java b/org.springframework.context/src/main/java/org/springframework/scheduling/concurrent/ConcurrentTaskScheduler.java index da79d35ade5..ff4cf939e78 100644 --- a/org.springframework.context/src/main/java/org/springframework/scheduling/concurrent/ConcurrentTaskScheduler.java +++ b/org.springframework.context/src/main/java/org/springframework/scheduling/concurrent/ConcurrentTaskScheduler.java @@ -1,187 +1,187 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.scheduling.concurrent; - -import java.util.Date; -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; -import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; - -import org.springframework.core.task.TaskRejectedException; -import org.springframework.scheduling.TaskScheduler; -import org.springframework.scheduling.Trigger; -import org.springframework.scheduling.support.TaskUtils; -import org.springframework.util.Assert; -import org.springframework.util.ErrorHandler; - -/** - * Adapter that takes a JDK 1.5 <code>java.util.concurrent.ScheduledExecutorService</code> - * and exposes a Spring {@link org.springframework.scheduling.TaskScheduler} for it. - * Extends {@link ConcurrentTaskExecutor} in order to implement the - * {@link org.springframework.scheduling.SchedulingTaskExecutor} interface as well. - * - * <p>Note that there is a pre-built {@link ThreadPoolTaskScheduler} that allows for - * defining a JDK 1.5 {@link java.util.concurrent.ScheduledThreadPoolExecutor} in bean style, - * exposing it as a Spring {@link org.springframework.scheduling.TaskScheduler} directly. - * This is a convenient alternative to a raw ScheduledThreadPoolExecutor definition with - * a separate definition of the present adapter class. - * - * @author Juergen Hoeller - * @author Mark Fisher - * @since 3.0 - * @see java.util.concurrent.ScheduledExecutorService - * @see java.util.concurrent.ScheduledThreadPoolExecutor - * @see java.util.concurrent.Executors - * @see ThreadPoolTaskScheduler - */ -public class ConcurrentTaskScheduler extends ConcurrentTaskExecutor implements TaskScheduler { - - private volatile ScheduledExecutorService scheduledExecutor; - - private volatile ErrorHandler errorHandler; - - - /** - * Create a new ConcurrentTaskScheduler, - * using a single thread executor as default. - * @see java.util.concurrent.Executors#newSingleThreadScheduledExecutor() - */ - public ConcurrentTaskScheduler() { - super(); - setScheduledExecutor(null); - } - - /** - * Create a new ConcurrentTaskScheduler, - * using the given JDK 1.5 executor as shared delegate. - * @param scheduledExecutor the JDK 1.5 scheduled executor to delegate to - * for {@link org.springframework.scheduling.SchedulingTaskExecutor} as well - * as {@link TaskScheduler} invocations - */ - public ConcurrentTaskScheduler(ScheduledExecutorService scheduledExecutor) { - super(scheduledExecutor); - setScheduledExecutor(scheduledExecutor); - } - - /** - * Create a new ConcurrentTaskScheduler, - * using the given JDK 1.5 executors as delegates. - * @param concurrentExecutor the JDK 1.5 concurrent executor to delegate to - * for {@link org.springframework.scheduling.SchedulingTaskExecutor} invocations - * @param scheduledExecutor the JDK 1.5 scheduled executor to delegate to - * for {@link TaskScheduler} invocations - */ - public ConcurrentTaskScheduler(Executor concurrentExecutor, ScheduledExecutorService scheduledExecutor) { - super(concurrentExecutor); - setScheduledExecutor(scheduledExecutor); - } - - - /** - * Specify the JDK 1.5 scheduled executor to delegate to. - * <p>Note: This will only apply to {@link TaskScheduler} invocations. - * If you want the given executor to apply to - * {@link org.springframework.scheduling.SchedulingTaskExecutor} invocations - * as well, pass the same executor reference to {@link #setConcurrentExecutor}. - * @see #setConcurrentExecutor - */ - public final void setScheduledExecutor(ScheduledExecutorService scheduledExecutor) { - this.scheduledExecutor = - (scheduledExecutor != null ? scheduledExecutor : Executors.newSingleThreadScheduledExecutor()); - } - - /** - * Provide an {@link ErrorHandler} strategy. - */ - public void setErrorHandler(ErrorHandler errorHandler) { - Assert.notNull(errorHandler, "'errorHandler' must not be null"); - this.errorHandler = errorHandler; - } - - - public ScheduledFuture schedule(Runnable task, Trigger trigger) { - try { - ErrorHandler errorHandler = - (this.errorHandler != null ? this.errorHandler : TaskUtils.getDefaultErrorHandler(true)); - return new ReschedulingRunnable(task, trigger, this.scheduledExecutor, errorHandler).schedule(); - } - catch (RejectedExecutionException ex) { - throw new TaskRejectedException("Executor [" + this.scheduledExecutor + "] did not accept task: " + task, ex); - } - } - - public ScheduledFuture schedule(Runnable task, Date startTime) { - long initialDelay = startTime.getTime() - System.currentTimeMillis(); - try { - return this.scheduledExecutor.schedule( - errorHandlingTask(task, false), initialDelay, TimeUnit.MILLISECONDS); - } - catch (RejectedExecutionException ex) { - throw new TaskRejectedException("Executor [" + this.scheduledExecutor + "] did not accept task: " + task, ex); - } - } - - public ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period) { - long initialDelay = startTime.getTime() - System.currentTimeMillis(); - try { - return this.scheduledExecutor.scheduleAtFixedRate( - errorHandlingTask(task, true), initialDelay, period, TimeUnit.MILLISECONDS); - } - catch (RejectedExecutionException ex) { - throw new TaskRejectedException("Executor [" + this.scheduledExecutor + "] did not accept task: " + task, ex); - } - } - - public ScheduledFuture scheduleAtFixedRate(Runnable task, long period) { - try { - return this.scheduledExecutor.scheduleAtFixedRate( - errorHandlingTask(task, true), 0, period, TimeUnit.MILLISECONDS); - } - catch (RejectedExecutionException ex) { - throw new TaskRejectedException("Executor [" + this.scheduledExecutor + "] did not accept task: " + task, ex); - } - } - - public ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay) { - long initialDelay = startTime.getTime() - System.currentTimeMillis(); - try { - return this.scheduledExecutor.scheduleWithFixedDelay( - errorHandlingTask(task, true), initialDelay, delay, TimeUnit.MILLISECONDS); - } - catch (RejectedExecutionException ex) { - throw new TaskRejectedException("Executor [" + this.scheduledExecutor + "] did not accept task: " + task, ex); - } - } - - public ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay) { - try { - return this.scheduledExecutor.scheduleWithFixedDelay( - errorHandlingTask(task, true), 0, delay, TimeUnit.MILLISECONDS); - } - catch (RejectedExecutionException ex) { - throw new TaskRejectedException("Executor [" + this.scheduledExecutor + "] did not accept task: " + task, ex); - } - } - - private Runnable errorHandlingTask(Runnable task, boolean isRepeatingTask) { - return TaskUtils.decorateTaskWithErrorHandler(task, this.errorHandler, isRepeatingTask); - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.scheduling.concurrent; + +import java.util.Date; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +import org.springframework.core.task.TaskRejectedException; +import org.springframework.scheduling.TaskScheduler; +import org.springframework.scheduling.Trigger; +import org.springframework.scheduling.support.TaskUtils; +import org.springframework.util.Assert; +import org.springframework.util.ErrorHandler; + +/** + * Adapter that takes a JDK 1.5 <code>java.util.concurrent.ScheduledExecutorService</code> + * and exposes a Spring {@link org.springframework.scheduling.TaskScheduler} for it. + * Extends {@link ConcurrentTaskExecutor} in order to implement the + * {@link org.springframework.scheduling.SchedulingTaskExecutor} interface as well. + * + * <p>Note that there is a pre-built {@link ThreadPoolTaskScheduler} that allows for + * defining a JDK 1.5 {@link java.util.concurrent.ScheduledThreadPoolExecutor} in bean style, + * exposing it as a Spring {@link org.springframework.scheduling.TaskScheduler} directly. + * This is a convenient alternative to a raw ScheduledThreadPoolExecutor definition with + * a separate definition of the present adapter class. + * + * @author Juergen Hoeller + * @author Mark Fisher + * @since 3.0 + * @see java.util.concurrent.ScheduledExecutorService + * @see java.util.concurrent.ScheduledThreadPoolExecutor + * @see java.util.concurrent.Executors + * @see ThreadPoolTaskScheduler + */ +public class ConcurrentTaskScheduler extends ConcurrentTaskExecutor implements TaskScheduler { + + private volatile ScheduledExecutorService scheduledExecutor; + + private volatile ErrorHandler errorHandler; + + + /** + * Create a new ConcurrentTaskScheduler, + * using a single thread executor as default. + * @see java.util.concurrent.Executors#newSingleThreadScheduledExecutor() + */ + public ConcurrentTaskScheduler() { + super(); + setScheduledExecutor(null); + } + + /** + * Create a new ConcurrentTaskScheduler, + * using the given JDK 1.5 executor as shared delegate. + * @param scheduledExecutor the JDK 1.5 scheduled executor to delegate to + * for {@link org.springframework.scheduling.SchedulingTaskExecutor} as well + * as {@link TaskScheduler} invocations + */ + public ConcurrentTaskScheduler(ScheduledExecutorService scheduledExecutor) { + super(scheduledExecutor); + setScheduledExecutor(scheduledExecutor); + } + + /** + * Create a new ConcurrentTaskScheduler, + * using the given JDK 1.5 executors as delegates. + * @param concurrentExecutor the JDK 1.5 concurrent executor to delegate to + * for {@link org.springframework.scheduling.SchedulingTaskExecutor} invocations + * @param scheduledExecutor the JDK 1.5 scheduled executor to delegate to + * for {@link TaskScheduler} invocations + */ + public ConcurrentTaskScheduler(Executor concurrentExecutor, ScheduledExecutorService scheduledExecutor) { + super(concurrentExecutor); + setScheduledExecutor(scheduledExecutor); + } + + + /** + * Specify the JDK 1.5 scheduled executor to delegate to. + * <p>Note: This will only apply to {@link TaskScheduler} invocations. + * If you want the given executor to apply to + * {@link org.springframework.scheduling.SchedulingTaskExecutor} invocations + * as well, pass the same executor reference to {@link #setConcurrentExecutor}. + * @see #setConcurrentExecutor + */ + public final void setScheduledExecutor(ScheduledExecutorService scheduledExecutor) { + this.scheduledExecutor = + (scheduledExecutor != null ? scheduledExecutor : Executors.newSingleThreadScheduledExecutor()); + } + + /** + * Provide an {@link ErrorHandler} strategy. + */ + public void setErrorHandler(ErrorHandler errorHandler) { + Assert.notNull(errorHandler, "'errorHandler' must not be null"); + this.errorHandler = errorHandler; + } + + + public ScheduledFuture schedule(Runnable task, Trigger trigger) { + try { + ErrorHandler errorHandler = + (this.errorHandler != null ? this.errorHandler : TaskUtils.getDefaultErrorHandler(true)); + return new ReschedulingRunnable(task, trigger, this.scheduledExecutor, errorHandler).schedule(); + } + catch (RejectedExecutionException ex) { + throw new TaskRejectedException("Executor [" + this.scheduledExecutor + "] did not accept task: " + task, ex); + } + } + + public ScheduledFuture schedule(Runnable task, Date startTime) { + long initialDelay = startTime.getTime() - System.currentTimeMillis(); + try { + return this.scheduledExecutor.schedule( + errorHandlingTask(task, false), initialDelay, TimeUnit.MILLISECONDS); + } + catch (RejectedExecutionException ex) { + throw new TaskRejectedException("Executor [" + this.scheduledExecutor + "] did not accept task: " + task, ex); + } + } + + public ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period) { + long initialDelay = startTime.getTime() - System.currentTimeMillis(); + try { + return this.scheduledExecutor.scheduleAtFixedRate( + errorHandlingTask(task, true), initialDelay, period, TimeUnit.MILLISECONDS); + } + catch (RejectedExecutionException ex) { + throw new TaskRejectedException("Executor [" + this.scheduledExecutor + "] did not accept task: " + task, ex); + } + } + + public ScheduledFuture scheduleAtFixedRate(Runnable task, long period) { + try { + return this.scheduledExecutor.scheduleAtFixedRate( + errorHandlingTask(task, true), 0, period, TimeUnit.MILLISECONDS); + } + catch (RejectedExecutionException ex) { + throw new TaskRejectedException("Executor [" + this.scheduledExecutor + "] did not accept task: " + task, ex); + } + } + + public ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay) { + long initialDelay = startTime.getTime() - System.currentTimeMillis(); + try { + return this.scheduledExecutor.scheduleWithFixedDelay( + errorHandlingTask(task, true), initialDelay, delay, TimeUnit.MILLISECONDS); + } + catch (RejectedExecutionException ex) { + throw new TaskRejectedException("Executor [" + this.scheduledExecutor + "] did not accept task: " + task, ex); + } + } + + public ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay) { + try { + return this.scheduledExecutor.scheduleWithFixedDelay( + errorHandlingTask(task, true), 0, delay, TimeUnit.MILLISECONDS); + } + catch (RejectedExecutionException ex) { + throw new TaskRejectedException("Executor [" + this.scheduledExecutor + "] did not accept task: " + task, ex); + } + } + + private Runnable errorHandlingTask(Runnable task, boolean isRepeatingTask) { + return TaskUtils.decorateTaskWithErrorHandler(task, this.errorHandler, isRepeatingTask); + } + +} diff --git a/org.springframework.context/src/main/java/org/springframework/scheduling/concurrent/ExecutorConfigurationSupport.java b/org.springframework.context/src/main/java/org/springframework/scheduling/concurrent/ExecutorConfigurationSupport.java index 1f8c37c31ec..56bbca108ff 100644 --- a/org.springframework.context/src/main/java/org/springframework/scheduling/concurrent/ExecutorConfigurationSupport.java +++ b/org.springframework.context/src/main/java/org/springframework/scheduling/concurrent/ExecutorConfigurationSupport.java @@ -1,160 +1,160 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.scheduling.concurrent; - -import java.util.concurrent.ExecutorService; -import java.util.concurrent.RejectedExecutionHandler; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.ThreadPoolExecutor; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.factory.BeanNameAware; -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.InitializingBean; - -/** - * Base class for classes that are setting up a - * <code>java.util.concurrent.ExecutorService</code> - * (typically a {@link java.util.concurrent.ThreadPoolExecutor}). - * Defines common configuration settings and common lifecycle handling. - * - * @author Juergen Hoeller - * @since 3.0 - * @see java.util.concurrent.ExecutorService - * @see java.util.concurrent.Executors - * @see java.util.concurrent.ThreadPoolExecutor - */ -public abstract class ExecutorConfigurationSupport extends CustomizableThreadFactory - implements BeanNameAware, InitializingBean, DisposableBean { - - protected final Log logger = LogFactory.getLog(getClass()); - - private ThreadFactory threadFactory = this; - - private boolean threadNamePrefixSet = false; - - private RejectedExecutionHandler rejectedExecutionHandler = new ThreadPoolExecutor.AbortPolicy(); - - private boolean waitForTasksToCompleteOnShutdown = false; - - private String beanName; - - private ExecutorService executor; - - - /** - * Set the ThreadFactory to use for the ThreadPoolExecutor's thread pool. - * Default is the ThreadPoolExecutor's default thread factory. - * @see java.util.concurrent.Executors#defaultThreadFactory() - */ - public void setThreadFactory(ThreadFactory threadFactory) { - this.threadFactory = (threadFactory != null ? threadFactory : this); - } - - @Override - public void setThreadNamePrefix(String threadNamePrefix) { - super.setThreadNamePrefix(threadNamePrefix); - this.threadNamePrefixSet = true; - } - - /** - * Set the RejectedExecutionHandler to use for the ThreadPoolExecutor. - * Default is the ThreadPoolExecutor's default abort policy. - * @see java.util.concurrent.ThreadPoolExecutor.AbortPolicy - */ - public void setRejectedExecutionHandler(RejectedExecutionHandler rejectedExecutionHandler) { - this.rejectedExecutionHandler = - (rejectedExecutionHandler != null ? rejectedExecutionHandler : new ThreadPoolExecutor.AbortPolicy()); - } - - /** - * Set whether to wait for scheduled tasks to complete on shutdown. - * <p>Default is "false". Switch this to "true" if you prefer - * fully completed tasks at the expense of a longer shutdown phase. - * @see java.util.concurrent.ExecutorService#shutdown() - * @see java.util.concurrent.ExecutorService#shutdownNow() - */ - public void setWaitForTasksToCompleteOnShutdown(boolean waitForJobsToCompleteOnShutdown) { - this.waitForTasksToCompleteOnShutdown = waitForJobsToCompleteOnShutdown; - } - - public void setBeanName(String name) { - this.beanName = name; - } - - - /** - * Calls <code>initialize()</code> after the container applied all property values. - * @see #initialize() - */ - public void afterPropertiesSet() { - initialize(); - } - - /** - * Set up the ExecutorService. - */ - public void initialize() { - if (logger.isInfoEnabled()) { - logger.info("Initializing ExecutorService " + (this.beanName != null ? " '" + this.beanName + "'" : "")); - } - if (!this.threadNamePrefixSet && this.beanName != null) { - setThreadNamePrefix(this.beanName + "-"); - } - this.executor = initializeExecutor(this.threadFactory, this.rejectedExecutionHandler); - } - - /** - * Create the target {@link java.util.concurrent.ExecutorService} instance. - * Called by <code>afterPropertiesSet</code>. - * @param threadFactory the ThreadFactory to use - * @param rejectedExecutionHandler the RejectedExecutionHandler to use - * @return a new ExecutorService instance - * @see #afterPropertiesSet() - */ - protected abstract ExecutorService initializeExecutor( - ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler); - - - /** - * Calls <code>shutdown</code> when the BeanFactory destroys - * the task executor instance. - * @see #shutdown() - */ - public void destroy() { - shutdown(); - } - - /** - * Perform a shutdown on the ThreadPoolExecutor. - * @see java.util.concurrent.ExecutorService#shutdown() - */ - public void shutdown() { - if (logger.isInfoEnabled()) { - logger.info("Shutting down ExecutorService" + (this.beanName != null ? " '" + this.beanName + "'" : "")); - } - if (this.waitForTasksToCompleteOnShutdown) { - this.executor.shutdown(); - } - else { - this.executor.shutdownNow(); - } - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.scheduling.concurrent; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.RejectedExecutionHandler; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.springframework.beans.factory.BeanNameAware; +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.InitializingBean; + +/** + * Base class for classes that are setting up a + * <code>java.util.concurrent.ExecutorService</code> + * (typically a {@link java.util.concurrent.ThreadPoolExecutor}). + * Defines common configuration settings and common lifecycle handling. + * + * @author Juergen Hoeller + * @since 3.0 + * @see java.util.concurrent.ExecutorService + * @see java.util.concurrent.Executors + * @see java.util.concurrent.ThreadPoolExecutor + */ +public abstract class ExecutorConfigurationSupport extends CustomizableThreadFactory + implements BeanNameAware, InitializingBean, DisposableBean { + + protected final Log logger = LogFactory.getLog(getClass()); + + private ThreadFactory threadFactory = this; + + private boolean threadNamePrefixSet = false; + + private RejectedExecutionHandler rejectedExecutionHandler = new ThreadPoolExecutor.AbortPolicy(); + + private boolean waitForTasksToCompleteOnShutdown = false; + + private String beanName; + + private ExecutorService executor; + + + /** + * Set the ThreadFactory to use for the ThreadPoolExecutor's thread pool. + * Default is the ThreadPoolExecutor's default thread factory. + * @see java.util.concurrent.Executors#defaultThreadFactory() + */ + public void setThreadFactory(ThreadFactory threadFactory) { + this.threadFactory = (threadFactory != null ? threadFactory : this); + } + + @Override + public void setThreadNamePrefix(String threadNamePrefix) { + super.setThreadNamePrefix(threadNamePrefix); + this.threadNamePrefixSet = true; + } + + /** + * Set the RejectedExecutionHandler to use for the ThreadPoolExecutor. + * Default is the ThreadPoolExecutor's default abort policy. + * @see java.util.concurrent.ThreadPoolExecutor.AbortPolicy + */ + public void setRejectedExecutionHandler(RejectedExecutionHandler rejectedExecutionHandler) { + this.rejectedExecutionHandler = + (rejectedExecutionHandler != null ? rejectedExecutionHandler : new ThreadPoolExecutor.AbortPolicy()); + } + + /** + * Set whether to wait for scheduled tasks to complete on shutdown. + * <p>Default is "false". Switch this to "true" if you prefer + * fully completed tasks at the expense of a longer shutdown phase. + * @see java.util.concurrent.ExecutorService#shutdown() + * @see java.util.concurrent.ExecutorService#shutdownNow() + */ + public void setWaitForTasksToCompleteOnShutdown(boolean waitForJobsToCompleteOnShutdown) { + this.waitForTasksToCompleteOnShutdown = waitForJobsToCompleteOnShutdown; + } + + public void setBeanName(String name) { + this.beanName = name; + } + + + /** + * Calls <code>initialize()</code> after the container applied all property values. + * @see #initialize() + */ + public void afterPropertiesSet() { + initialize(); + } + + /** + * Set up the ExecutorService. + */ + public void initialize() { + if (logger.isInfoEnabled()) { + logger.info("Initializing ExecutorService " + (this.beanName != null ? " '" + this.beanName + "'" : "")); + } + if (!this.threadNamePrefixSet && this.beanName != null) { + setThreadNamePrefix(this.beanName + "-"); + } + this.executor = initializeExecutor(this.threadFactory, this.rejectedExecutionHandler); + } + + /** + * Create the target {@link java.util.concurrent.ExecutorService} instance. + * Called by <code>afterPropertiesSet</code>. + * @param threadFactory the ThreadFactory to use + * @param rejectedExecutionHandler the RejectedExecutionHandler to use + * @return a new ExecutorService instance + * @see #afterPropertiesSet() + */ + protected abstract ExecutorService initializeExecutor( + ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler); + + + /** + * Calls <code>shutdown</code> when the BeanFactory destroys + * the task executor instance. + * @see #shutdown() + */ + public void destroy() { + shutdown(); + } + + /** + * Perform a shutdown on the ThreadPoolExecutor. + * @see java.util.concurrent.ExecutorService#shutdown() + */ + public void shutdown() { + if (logger.isInfoEnabled()) { + logger.info("Shutting down ExecutorService" + (this.beanName != null ? " '" + this.beanName + "'" : "")); + } + if (this.waitForTasksToCompleteOnShutdown) { + this.executor.shutdown(); + } + else { + this.executor.shutdownNow(); + } + } + +} diff --git a/org.springframework.context/src/main/java/org/springframework/scheduling/concurrent/ReschedulingRunnable.java b/org.springframework.context/src/main/java/org/springframework/scheduling/concurrent/ReschedulingRunnable.java index f63a77bb065..729dc02e77d 100644 --- a/org.springframework.context/src/main/java/org/springframework/scheduling/concurrent/ReschedulingRunnable.java +++ b/org.springframework.context/src/main/java/org/springframework/scheduling/concurrent/ReschedulingRunnable.java @@ -1,124 +1,124 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.scheduling.concurrent; - -import java.util.Date; -import java.util.concurrent.Delayed; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -import org.springframework.scheduling.Trigger; -import org.springframework.scheduling.support.DelegatingErrorHandlingRunnable; -import org.springframework.scheduling.support.SimpleTriggerContext; -import org.springframework.util.ErrorHandler; - -/** - * Internal adapter that reschedules an underlying {@link Runnable} according - * to the next execution time suggested by a given {@link Trigger}. - * - * <p>Necessary because a native {@link ScheduledExecutorService} supports - * delay-driven execution only. The flexibility of the {@link Trigger} interface - * will be translated onto a delay for the next execution time (repeatedly). - * - * @author Juergen Hoeller - * @author Mark Fisher - * @since 3.0 - */ -class ReschedulingRunnable extends DelegatingErrorHandlingRunnable implements ScheduledFuture<Object> { - - private final Trigger trigger; - - private final SimpleTriggerContext triggerContext = new SimpleTriggerContext(); - - private final ScheduledExecutorService executor; - - private volatile ScheduledFuture currentFuture; - - private volatile Date scheduledExecutionTime; - - private final Object triggerContextMonitor = new Object(); - - - public ReschedulingRunnable(Runnable delegate, Trigger trigger, ScheduledExecutorService executor, ErrorHandler errorHandler) { - super(delegate, errorHandler); - this.trigger = trigger; - this.executor = executor; - } - - - public ScheduledFuture schedule() { - synchronized (this.triggerContextMonitor) { - this.scheduledExecutionTime = this.trigger.nextExecutionTime(this.triggerContext); - if (this.scheduledExecutionTime == null) { - return null; - } - long initialDelay = this.scheduledExecutionTime.getTime() - System.currentTimeMillis(); - this.currentFuture = this.executor.schedule(this, initialDelay, TimeUnit.MILLISECONDS); - return this; - } - } - - @Override - public void run() { - Date actualExecutionTime = new Date(); - super.run(); - Date completionTime = new Date(); - synchronized (this.triggerContextMonitor) { - this.triggerContext.update(this.scheduledExecutionTime, actualExecutionTime, completionTime); - } - if (!this.currentFuture.isCancelled()) { - schedule(); - } - } - - - public boolean cancel(boolean mayInterruptIfRunning) { - return this.currentFuture.cancel(mayInterruptIfRunning); - } - - public boolean isCancelled() { - return this.currentFuture.isCancelled(); - } - - public boolean isDone() { - return this.currentFuture.isDone(); - } - - public Object get() throws InterruptedException, ExecutionException { - return this.currentFuture.get(); - } - - public Object get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { - return this.currentFuture.get(timeout, unit); - } - - public long getDelay(TimeUnit unit) { - return this.currentFuture.getDelay(unit); - } - - public int compareTo(Delayed other) { - if (this == other) { - return 0; - } - long diff = getDelay(TimeUnit.MILLISECONDS) - other.getDelay(TimeUnit.MILLISECONDS); - return (diff == 0 ? 0 : ((diff < 0)? -1 : 1)); - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.scheduling.concurrent; + +import java.util.Date; +import java.util.concurrent.Delayed; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import org.springframework.scheduling.Trigger; +import org.springframework.scheduling.support.DelegatingErrorHandlingRunnable; +import org.springframework.scheduling.support.SimpleTriggerContext; +import org.springframework.util.ErrorHandler; + +/** + * Internal adapter that reschedules an underlying {@link Runnable} according + * to the next execution time suggested by a given {@link Trigger}. + * + * <p>Necessary because a native {@link ScheduledExecutorService} supports + * delay-driven execution only. The flexibility of the {@link Trigger} interface + * will be translated onto a delay for the next execution time (repeatedly). + * + * @author Juergen Hoeller + * @author Mark Fisher + * @since 3.0 + */ +class ReschedulingRunnable extends DelegatingErrorHandlingRunnable implements ScheduledFuture<Object> { + + private final Trigger trigger; + + private final SimpleTriggerContext triggerContext = new SimpleTriggerContext(); + + private final ScheduledExecutorService executor; + + private volatile ScheduledFuture currentFuture; + + private volatile Date scheduledExecutionTime; + + private final Object triggerContextMonitor = new Object(); + + + public ReschedulingRunnable(Runnable delegate, Trigger trigger, ScheduledExecutorService executor, ErrorHandler errorHandler) { + super(delegate, errorHandler); + this.trigger = trigger; + this.executor = executor; + } + + + public ScheduledFuture schedule() { + synchronized (this.triggerContextMonitor) { + this.scheduledExecutionTime = this.trigger.nextExecutionTime(this.triggerContext); + if (this.scheduledExecutionTime == null) { + return null; + } + long initialDelay = this.scheduledExecutionTime.getTime() - System.currentTimeMillis(); + this.currentFuture = this.executor.schedule(this, initialDelay, TimeUnit.MILLISECONDS); + return this; + } + } + + @Override + public void run() { + Date actualExecutionTime = new Date(); + super.run(); + Date completionTime = new Date(); + synchronized (this.triggerContextMonitor) { + this.triggerContext.update(this.scheduledExecutionTime, actualExecutionTime, completionTime); + } + if (!this.currentFuture.isCancelled()) { + schedule(); + } + } + + + public boolean cancel(boolean mayInterruptIfRunning) { + return this.currentFuture.cancel(mayInterruptIfRunning); + } + + public boolean isCancelled() { + return this.currentFuture.isCancelled(); + } + + public boolean isDone() { + return this.currentFuture.isDone(); + } + + public Object get() throws InterruptedException, ExecutionException { + return this.currentFuture.get(); + } + + public Object get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { + return this.currentFuture.get(timeout, unit); + } + + public long getDelay(TimeUnit unit) { + return this.currentFuture.getDelay(unit); + } + + public int compareTo(Delayed other) { + if (this == other) { + return 0; + } + long diff = getDelay(TimeUnit.MILLISECONDS) - other.getDelay(TimeUnit.MILLISECONDS); + return (diff == 0 ? 0 : ((diff < 0)? -1 : 1)); + } + +} diff --git a/org.springframework.context/src/main/java/org/springframework/scheduling/concurrent/ThreadPoolTaskScheduler.java b/org.springframework.context/src/main/java/org/springframework/scheduling/concurrent/ThreadPoolTaskScheduler.java index fa42583444b..c78ba7876e5 100644 --- a/org.springframework.context/src/main/java/org/springframework/scheduling/concurrent/ThreadPoolTaskScheduler.java +++ b/org.springframework.context/src/main/java/org/springframework/scheduling/concurrent/ThreadPoolTaskScheduler.java @@ -1,251 +1,251 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.scheduling.concurrent; - -import java.util.Date; -import java.util.concurrent.Callable; -import java.util.concurrent.Executor; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; -import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.RejectedExecutionHandler; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.TimeUnit; - -import org.springframework.core.task.TaskRejectedException; -import org.springframework.scheduling.SchedulingTaskExecutor; -import org.springframework.scheduling.TaskScheduler; -import org.springframework.scheduling.Trigger; -import org.springframework.scheduling.support.TaskUtils; -import org.springframework.util.Assert; -import org.springframework.util.ErrorHandler; - -/** - * Implementation of Spring's {@link TaskScheduler} interface, wrapping - * a native {@link java.util.concurrent.ScheduledThreadPoolExecutor}. - * - * @author Juergen Hoeller - * @author Mark Fisher - * @since 3.0 - * @see #setPoolSize - * @see #setThreadFactory - * @see #setErrorHandler - */ -public class ThreadPoolTaskScheduler extends ExecutorConfigurationSupport - implements TaskScheduler, SchedulingTaskExecutor { - - private volatile int poolSize = 1; - - private volatile ScheduledExecutorService scheduledExecutor; - - private volatile ErrorHandler errorHandler; - - - /** - * Set the ScheduledExecutorService's pool size. - * Default is 1. - */ - public void setPoolSize(int poolSize) { - Assert.isTrue(poolSize > 0, "'poolSize' must be 1 or higher"); - this.poolSize = poolSize; - } - - /** - * Provide an {@link ErrorHandler} strategy. - */ - public void setErrorHandler(ErrorHandler errorHandler) { - Assert.notNull(errorHandler, "'errorHandler' must not be null"); - this.errorHandler = errorHandler; - } - - protected ExecutorService initializeExecutor( - ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler) { - - this.scheduledExecutor = createExecutor(this.poolSize, threadFactory, rejectedExecutionHandler); - return this.scheduledExecutor; - } - - /** - * Create a new {@link ScheduledExecutorService} instance. - * <p>The default implementation creates a {@link ScheduledThreadPoolExecutor}. - * Can be overridden in subclasses to provide custom {@link ScheduledExecutorService} instances. - * @param poolSize the specified pool size - * @param threadFactory the ThreadFactory to use - * @param rejectedExecutionHandler the RejectedExecutionHandler to use - * @return a new ScheduledExecutorService instance - * @see #afterPropertiesSet() - * @see java.util.concurrent.ScheduledThreadPoolExecutor - */ - protected ScheduledExecutorService createExecutor( - int poolSize, ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler) { - - return new ScheduledThreadPoolExecutor(poolSize, threadFactory, rejectedExecutionHandler); - } - - /** - * Return the underlying ScheduledExecutorService for native access. - * @return the underlying ScheduledExecutorService (never <code>null</code>) - * @throws IllegalStateException if the ThreadPoolTaskScheduler hasn't been initialized yet - */ - public ScheduledExecutorService getScheduledExecutor() throws IllegalStateException { - Assert.state(this.scheduledExecutor != null, "ThreadPoolTaskScheduler not initialized"); - return this.scheduledExecutor; - } - - - // SchedulingTaskExecutor implementation - - public void execute(Runnable task) { - Executor executor = getScheduledExecutor(); - try { - executor.execute(errorHandlingTask(task, false)); - } - catch (RejectedExecutionException ex) { - throw new TaskRejectedException("Executor [" + executor + "] did not accept task: " + task, ex); - } - } - - public void execute(Runnable task, long startTimeout) { - execute(task); - } - - public Future<?> submit(Runnable task) { - ExecutorService executor = getScheduledExecutor(); - try { - return executor.submit(errorHandlingTask(task, false)); - } - catch (RejectedExecutionException ex) { - throw new TaskRejectedException("Executor [" + executor + "] did not accept task: " + task, ex); - } - } - - public <T> Future<T> submit(Callable<T> task) { - ExecutorService executor = getScheduledExecutor(); - try { - if (this.errorHandler != null) { - task = new DelegatingErrorHandlingCallable<T>(task, this.errorHandler); - } - return executor.submit(task); - } - catch (RejectedExecutionException ex) { - throw new TaskRejectedException("Executor [" + executor + "] did not accept task: " + task, ex); - } - } - - public boolean prefersShortLivedTasks() { - return true; - } - - - // TaskScheduler implementation - - public ScheduledFuture schedule(Runnable task, Trigger trigger) { - ScheduledExecutorService executor = getScheduledExecutor(); - try { - ErrorHandler errorHandler = - (this.errorHandler != null ? this.errorHandler : TaskUtils.getDefaultErrorHandler(true)); - return new ReschedulingRunnable(task, trigger, executor, errorHandler).schedule(); - } - catch (RejectedExecutionException ex) { - throw new TaskRejectedException("Executor [" + executor + "] did not accept task: " + task, ex); - } - } - - public ScheduledFuture schedule(Runnable task, Date startTime) { - ScheduledExecutorService executor = getScheduledExecutor(); - long initialDelay = startTime.getTime() - System.currentTimeMillis(); - try { - return executor.schedule(errorHandlingTask(task, false), initialDelay, TimeUnit.MILLISECONDS); - } - catch (RejectedExecutionException ex) { - throw new TaskRejectedException("Executor [" + executor + "] did not accept task: " + task, ex); - } - } - - public ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period) { - ScheduledExecutorService executor = getScheduledExecutor(); - long initialDelay = startTime.getTime() - System.currentTimeMillis(); - try { - return executor.scheduleAtFixedRate(errorHandlingTask(task, true), initialDelay, period, TimeUnit.MILLISECONDS); - } - catch (RejectedExecutionException ex) { - throw new TaskRejectedException("Executor [" + executor + "] did not accept task: " + task, ex); - } - } - - public ScheduledFuture scheduleAtFixedRate(Runnable task, long period) { - ScheduledExecutorService executor = getScheduledExecutor(); - try { - return executor.scheduleAtFixedRate(errorHandlingTask(task, true), 0, period, TimeUnit.MILLISECONDS); - } - catch (RejectedExecutionException ex) { - throw new TaskRejectedException("Executor [" + executor + "] did not accept task: " + task, ex); - } - } - - public ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay) { - ScheduledExecutorService executor = getScheduledExecutor(); - long initialDelay = startTime.getTime() - System.currentTimeMillis(); - try { - return executor.scheduleWithFixedDelay(errorHandlingTask(task, true), initialDelay, delay, TimeUnit.MILLISECONDS); - } - catch (RejectedExecutionException ex) { - throw new TaskRejectedException("Executor [" + executor + "] did not accept task: " + task, ex); - } - } - - public ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay) { - ScheduledExecutorService executor = getScheduledExecutor(); - try { - return executor.scheduleWithFixedDelay(errorHandlingTask(task, true), 0, delay, TimeUnit.MILLISECONDS); - } - catch (RejectedExecutionException ex) { - throw new TaskRejectedException("Executor [" + executor + "] did not accept task: " + task, ex); - } - } - - private Runnable errorHandlingTask(Runnable task, boolean isRepeatingTask) { - return TaskUtils.decorateTaskWithErrorHandler(task, this.errorHandler, isRepeatingTask); - } - - - private static class DelegatingErrorHandlingCallable<V> implements Callable<V> { - - private final Callable<V> delegate; - - private final ErrorHandler errorHandler; - - DelegatingErrorHandlingCallable(Callable<V> delegate, ErrorHandler errorHandler) { - this.delegate = delegate; - this.errorHandler = errorHandler; - } - - public V call() throws Exception { - try { - return delegate.call(); - } - catch (Throwable t) { - this.errorHandler.handleError(t); - return null; - } - } - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.scheduling.concurrent; + +import java.util.Date; +import java.util.concurrent.Callable; +import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.RejectedExecutionHandler; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; + +import org.springframework.core.task.TaskRejectedException; +import org.springframework.scheduling.SchedulingTaskExecutor; +import org.springframework.scheduling.TaskScheduler; +import org.springframework.scheduling.Trigger; +import org.springframework.scheduling.support.TaskUtils; +import org.springframework.util.Assert; +import org.springframework.util.ErrorHandler; + +/** + * Implementation of Spring's {@link TaskScheduler} interface, wrapping + * a native {@link java.util.concurrent.ScheduledThreadPoolExecutor}. + * + * @author Juergen Hoeller + * @author Mark Fisher + * @since 3.0 + * @see #setPoolSize + * @see #setThreadFactory + * @see #setErrorHandler + */ +public class ThreadPoolTaskScheduler extends ExecutorConfigurationSupport + implements TaskScheduler, SchedulingTaskExecutor { + + private volatile int poolSize = 1; + + private volatile ScheduledExecutorService scheduledExecutor; + + private volatile ErrorHandler errorHandler; + + + /** + * Set the ScheduledExecutorService's pool size. + * Default is 1. + */ + public void setPoolSize(int poolSize) { + Assert.isTrue(poolSize > 0, "'poolSize' must be 1 or higher"); + this.poolSize = poolSize; + } + + /** + * Provide an {@link ErrorHandler} strategy. + */ + public void setErrorHandler(ErrorHandler errorHandler) { + Assert.notNull(errorHandler, "'errorHandler' must not be null"); + this.errorHandler = errorHandler; + } + + protected ExecutorService initializeExecutor( + ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler) { + + this.scheduledExecutor = createExecutor(this.poolSize, threadFactory, rejectedExecutionHandler); + return this.scheduledExecutor; + } + + /** + * Create a new {@link ScheduledExecutorService} instance. + * <p>The default implementation creates a {@link ScheduledThreadPoolExecutor}. + * Can be overridden in subclasses to provide custom {@link ScheduledExecutorService} instances. + * @param poolSize the specified pool size + * @param threadFactory the ThreadFactory to use + * @param rejectedExecutionHandler the RejectedExecutionHandler to use + * @return a new ScheduledExecutorService instance + * @see #afterPropertiesSet() + * @see java.util.concurrent.ScheduledThreadPoolExecutor + */ + protected ScheduledExecutorService createExecutor( + int poolSize, ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler) { + + return new ScheduledThreadPoolExecutor(poolSize, threadFactory, rejectedExecutionHandler); + } + + /** + * Return the underlying ScheduledExecutorService for native access. + * @return the underlying ScheduledExecutorService (never <code>null</code>) + * @throws IllegalStateException if the ThreadPoolTaskScheduler hasn't been initialized yet + */ + public ScheduledExecutorService getScheduledExecutor() throws IllegalStateException { + Assert.state(this.scheduledExecutor != null, "ThreadPoolTaskScheduler not initialized"); + return this.scheduledExecutor; + } + + + // SchedulingTaskExecutor implementation + + public void execute(Runnable task) { + Executor executor = getScheduledExecutor(); + try { + executor.execute(errorHandlingTask(task, false)); + } + catch (RejectedExecutionException ex) { + throw new TaskRejectedException("Executor [" + executor + "] did not accept task: " + task, ex); + } + } + + public void execute(Runnable task, long startTimeout) { + execute(task); + } + + public Future<?> submit(Runnable task) { + ExecutorService executor = getScheduledExecutor(); + try { + return executor.submit(errorHandlingTask(task, false)); + } + catch (RejectedExecutionException ex) { + throw new TaskRejectedException("Executor [" + executor + "] did not accept task: " + task, ex); + } + } + + public <T> Future<T> submit(Callable<T> task) { + ExecutorService executor = getScheduledExecutor(); + try { + if (this.errorHandler != null) { + task = new DelegatingErrorHandlingCallable<T>(task, this.errorHandler); + } + return executor.submit(task); + } + catch (RejectedExecutionException ex) { + throw new TaskRejectedException("Executor [" + executor + "] did not accept task: " + task, ex); + } + } + + public boolean prefersShortLivedTasks() { + return true; + } + + + // TaskScheduler implementation + + public ScheduledFuture schedule(Runnable task, Trigger trigger) { + ScheduledExecutorService executor = getScheduledExecutor(); + try { + ErrorHandler errorHandler = + (this.errorHandler != null ? this.errorHandler : TaskUtils.getDefaultErrorHandler(true)); + return new ReschedulingRunnable(task, trigger, executor, errorHandler).schedule(); + } + catch (RejectedExecutionException ex) { + throw new TaskRejectedException("Executor [" + executor + "] did not accept task: " + task, ex); + } + } + + public ScheduledFuture schedule(Runnable task, Date startTime) { + ScheduledExecutorService executor = getScheduledExecutor(); + long initialDelay = startTime.getTime() - System.currentTimeMillis(); + try { + return executor.schedule(errorHandlingTask(task, false), initialDelay, TimeUnit.MILLISECONDS); + } + catch (RejectedExecutionException ex) { + throw new TaskRejectedException("Executor [" + executor + "] did not accept task: " + task, ex); + } + } + + public ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period) { + ScheduledExecutorService executor = getScheduledExecutor(); + long initialDelay = startTime.getTime() - System.currentTimeMillis(); + try { + return executor.scheduleAtFixedRate(errorHandlingTask(task, true), initialDelay, period, TimeUnit.MILLISECONDS); + } + catch (RejectedExecutionException ex) { + throw new TaskRejectedException("Executor [" + executor + "] did not accept task: " + task, ex); + } + } + + public ScheduledFuture scheduleAtFixedRate(Runnable task, long period) { + ScheduledExecutorService executor = getScheduledExecutor(); + try { + return executor.scheduleAtFixedRate(errorHandlingTask(task, true), 0, period, TimeUnit.MILLISECONDS); + } + catch (RejectedExecutionException ex) { + throw new TaskRejectedException("Executor [" + executor + "] did not accept task: " + task, ex); + } + } + + public ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay) { + ScheduledExecutorService executor = getScheduledExecutor(); + long initialDelay = startTime.getTime() - System.currentTimeMillis(); + try { + return executor.scheduleWithFixedDelay(errorHandlingTask(task, true), initialDelay, delay, TimeUnit.MILLISECONDS); + } + catch (RejectedExecutionException ex) { + throw new TaskRejectedException("Executor [" + executor + "] did not accept task: " + task, ex); + } + } + + public ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay) { + ScheduledExecutorService executor = getScheduledExecutor(); + try { + return executor.scheduleWithFixedDelay(errorHandlingTask(task, true), 0, delay, TimeUnit.MILLISECONDS); + } + catch (RejectedExecutionException ex) { + throw new TaskRejectedException("Executor [" + executor + "] did not accept task: " + task, ex); + } + } + + private Runnable errorHandlingTask(Runnable task, boolean isRepeatingTask) { + return TaskUtils.decorateTaskWithErrorHandler(task, this.errorHandler, isRepeatingTask); + } + + + private static class DelegatingErrorHandlingCallable<V> implements Callable<V> { + + private final Callable<V> delegate; + + private final ErrorHandler errorHandler; + + DelegatingErrorHandlingCallable(Callable<V> delegate, ErrorHandler errorHandler) { + this.delegate = delegate; + this.errorHandler = errorHandler; + } + + public V call() throws Exception { + try { + return delegate.call(); + } + catch (Throwable t) { + this.errorHandler.handleError(t); + return null; + } + } + } + +} diff --git a/org.springframework.context/src/main/java/org/springframework/scheduling/config/ScheduledTaskRegistrar.java b/org.springframework.context/src/main/java/org/springframework/scheduling/config/ScheduledTaskRegistrar.java index 3f4adc49074..1898441e217 100644 --- a/org.springframework.context/src/main/java/org/springframework/scheduling/config/ScheduledTaskRegistrar.java +++ b/org.springframework.context/src/main/java/org/springframework/scheduling/config/ScheduledTaskRegistrar.java @@ -1,213 +1,213 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.scheduling.config; - -import java.util.HashMap; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; - -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.scheduling.TaskScheduler; -import org.springframework.scheduling.Trigger; -import org.springframework.scheduling.concurrent.ConcurrentTaskScheduler; -import org.springframework.scheduling.support.CronTrigger; -import org.springframework.util.Assert; - -/** - * Helper bean for registering tasks with a {@link TaskScheduler}, - * typically using cron expressions. - * - * <p>As of Spring 3.1, {@code ScheduledTaskRegistrar} has a more prominent user-facing - * role when used in conjunction with the @{@link - * org.springframework.scheduling.annotation.EnableAsync EnableAsync} annotation and its - * {@link org.springframework.scheduling.annotation.SchedulingConfigurer - * SchedulingConfigurer} callback interface. - * - * @author Juergen Hoeller - * @since 3.0 - * @see org.springframework.scheduling.annotation.EnableAsync - * @see org.springframework.scheduling.annotation.SchedulingConfigurer - */ -public class ScheduledTaskRegistrar implements InitializingBean, DisposableBean { - - private TaskScheduler taskScheduler; - - private ScheduledExecutorService localExecutor; - - private Map<Runnable, Trigger> triggerTasks; - - private Map<Runnable, String> cronTasks; - - private Map<Runnable, Long> fixedRateTasks; - - private Map<Runnable, Long> fixedDelayTasks; - - private final Set<ScheduledFuture<?>> scheduledFutures = new LinkedHashSet<ScheduledFuture<?>>(); - - - /** - * Set the TaskScheduler to register scheduled tasks with. - */ - public void setTaskScheduler(TaskScheduler taskScheduler) { - Assert.notNull(taskScheduler, "TaskScheduler must not be null"); - this.taskScheduler = taskScheduler; - } - - /** - * Set the {@link org.springframework.scheduling.TaskScheduler} to register scheduled - * tasks with, or a {@link java.util.concurrent.ScheduledExecutorService} to be - * wrapped as a TaskScheduler. - */ - public void setScheduler(Object scheduler) { - Assert.notNull(scheduler, "Scheduler object must not be null"); - if (scheduler instanceof TaskScheduler) { - this.taskScheduler = (TaskScheduler) scheduler; - } - else if (scheduler instanceof ScheduledExecutorService) { - this.taskScheduler = new ConcurrentTaskScheduler(((ScheduledExecutorService) scheduler)); - } - else { - throw new IllegalArgumentException("Unsupported scheduler type: " + scheduler.getClass()); - } - } - - /** - * Return the scheduler instance for this registrar (may be null) - */ - public TaskScheduler getScheduler() { - return this.taskScheduler; - } - - /** - * Specify triggered tasks as a Map of Runnables (the tasks) and Trigger objects - * (typically custom implementations of the {@link Trigger} interface). - */ - public void setTriggerTasks(Map<Runnable, Trigger> triggerTasks) { - this.triggerTasks = triggerTasks; - } - - /** - * Specify triggered tasks as a Map of Runnables (the tasks) and cron expressions. - * @see CronTrigger - */ - public void setCronTasks(Map<Runnable, String> cronTasks) { - this.cronTasks = cronTasks; - } - - /** - * Specify triggered tasks as a Map of Runnables (the tasks) and fixed-rate values. - * @see TaskScheduler#scheduleAtFixedRate(Runnable, long) - */ - public void setFixedRateTasks(Map<Runnable, Long> fixedRateTasks) { - this.fixedRateTasks = fixedRateTasks; - } - - /** - * Add a Runnable task to be triggered per the given {@link Trigger}. - * @see TaskScheduler#scheduleAtFixedRate(Runnable, long) - */ - public void addTriggerTask(Runnable task, Trigger trigger) { - if (this.triggerTasks == null) { - this.triggerTasks = new HashMap<Runnable, Trigger>(); - } - this.triggerTasks.put(task, trigger); - } - - /** - * Add a Runnable task to be triggered per the given cron expression - */ - public void addCronTask(Runnable task, String cronExpression) { - if (this.cronTasks == null) { - this.cronTasks = new HashMap<Runnable, String>(); - } - this.cronTasks.put(task, cronExpression); - } - - /** - * Add a Runnable task to be triggered with the given fixed delay. - * @see TaskScheduler#scheduleWithFixedDelay(Runnable, long) - */ - public void addFixedDelayTask(Runnable task, long delay) { - if (this.fixedDelayTasks == null) { - this.fixedDelayTasks = new HashMap<Runnable, Long>(); - } - this.fixedDelayTasks.put(task, delay); - } - - /** - * Add a Runnable task to be triggered at the given fixed-rate period. - * @see TaskScheduler#scheduleAtFixedRate(Runnable, long) - */ - public void addFixedRateTask(Runnable task, long period) { - if (this.fixedRateTasks == null) { - this.fixedRateTasks = new HashMap<Runnable, Long>(); - } - this.fixedRateTasks.put(task, period); - } - - /** - * Specify triggered tasks as a Map of Runnables (the tasks) and fixed-delay values. - * @see TaskScheduler#scheduleWithFixedDelay(Runnable, long) - */ - public void setFixedDelayTasks(Map<Runnable, Long> fixedDelayTasks) { - this.fixedDelayTasks = fixedDelayTasks; - } - - - public void afterPropertiesSet() { - if (this.taskScheduler == null) { - this.localExecutor = Executors.newSingleThreadScheduledExecutor(); - this.taskScheduler = new ConcurrentTaskScheduler(this.localExecutor); - } - if (this.triggerTasks != null) { - for (Map.Entry<Runnable, Trigger> entry : this.triggerTasks.entrySet()) { - this.scheduledFutures.add(this.taskScheduler.schedule(entry.getKey(), entry.getValue())); - } - } - if (this.cronTasks != null) { - for (Map.Entry<Runnable, String> entry : this.cronTasks.entrySet()) { - this.scheduledFutures.add(this.taskScheduler.schedule(entry.getKey(), new CronTrigger(entry.getValue()))); - } - } - if (this.fixedRateTasks != null) { - for (Map.Entry<Runnable, Long> entry : this.fixedRateTasks.entrySet()) { - this.scheduledFutures.add(this.taskScheduler.scheduleAtFixedRate(entry.getKey(), entry.getValue())); - } - } - if (this.fixedDelayTasks != null) { - for (Map.Entry<Runnable, Long> entry : this.fixedDelayTasks.entrySet()) { - this.scheduledFutures.add(this.taskScheduler.scheduleWithFixedDelay(entry.getKey(), entry.getValue())); - } - } - } - - - public void destroy() { - for (ScheduledFuture<?> future : this.scheduledFutures) { - future.cancel(true); - } - if (this.localExecutor != null) { - this.localExecutor.shutdownNow(); - } - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.scheduling.config; + +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; + +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.scheduling.TaskScheduler; +import org.springframework.scheduling.Trigger; +import org.springframework.scheduling.concurrent.ConcurrentTaskScheduler; +import org.springframework.scheduling.support.CronTrigger; +import org.springframework.util.Assert; + +/** + * Helper bean for registering tasks with a {@link TaskScheduler}, + * typically using cron expressions. + * + * <p>As of Spring 3.1, {@code ScheduledTaskRegistrar} has a more prominent user-facing + * role when used in conjunction with the @{@link + * org.springframework.scheduling.annotation.EnableAsync EnableAsync} annotation and its + * {@link org.springframework.scheduling.annotation.SchedulingConfigurer + * SchedulingConfigurer} callback interface. + * + * @author Juergen Hoeller + * @since 3.0 + * @see org.springframework.scheduling.annotation.EnableAsync + * @see org.springframework.scheduling.annotation.SchedulingConfigurer + */ +public class ScheduledTaskRegistrar implements InitializingBean, DisposableBean { + + private TaskScheduler taskScheduler; + + private ScheduledExecutorService localExecutor; + + private Map<Runnable, Trigger> triggerTasks; + + private Map<Runnable, String> cronTasks; + + private Map<Runnable, Long> fixedRateTasks; + + private Map<Runnable, Long> fixedDelayTasks; + + private final Set<ScheduledFuture<?>> scheduledFutures = new LinkedHashSet<ScheduledFuture<?>>(); + + + /** + * Set the TaskScheduler to register scheduled tasks with. + */ + public void setTaskScheduler(TaskScheduler taskScheduler) { + Assert.notNull(taskScheduler, "TaskScheduler must not be null"); + this.taskScheduler = taskScheduler; + } + + /** + * Set the {@link org.springframework.scheduling.TaskScheduler} to register scheduled + * tasks with, or a {@link java.util.concurrent.ScheduledExecutorService} to be + * wrapped as a TaskScheduler. + */ + public void setScheduler(Object scheduler) { + Assert.notNull(scheduler, "Scheduler object must not be null"); + if (scheduler instanceof TaskScheduler) { + this.taskScheduler = (TaskScheduler) scheduler; + } + else if (scheduler instanceof ScheduledExecutorService) { + this.taskScheduler = new ConcurrentTaskScheduler(((ScheduledExecutorService) scheduler)); + } + else { + throw new IllegalArgumentException("Unsupported scheduler type: " + scheduler.getClass()); + } + } + + /** + * Return the scheduler instance for this registrar (may be null) + */ + public TaskScheduler getScheduler() { + return this.taskScheduler; + } + + /** + * Specify triggered tasks as a Map of Runnables (the tasks) and Trigger objects + * (typically custom implementations of the {@link Trigger} interface). + */ + public void setTriggerTasks(Map<Runnable, Trigger> triggerTasks) { + this.triggerTasks = triggerTasks; + } + + /** + * Specify triggered tasks as a Map of Runnables (the tasks) and cron expressions. + * @see CronTrigger + */ + public void setCronTasks(Map<Runnable, String> cronTasks) { + this.cronTasks = cronTasks; + } + + /** + * Specify triggered tasks as a Map of Runnables (the tasks) and fixed-rate values. + * @see TaskScheduler#scheduleAtFixedRate(Runnable, long) + */ + public void setFixedRateTasks(Map<Runnable, Long> fixedRateTasks) { + this.fixedRateTasks = fixedRateTasks; + } + + /** + * Add a Runnable task to be triggered per the given {@link Trigger}. + * @see TaskScheduler#scheduleAtFixedRate(Runnable, long) + */ + public void addTriggerTask(Runnable task, Trigger trigger) { + if (this.triggerTasks == null) { + this.triggerTasks = new HashMap<Runnable, Trigger>(); + } + this.triggerTasks.put(task, trigger); + } + + /** + * Add a Runnable task to be triggered per the given cron expression + */ + public void addCronTask(Runnable task, String cronExpression) { + if (this.cronTasks == null) { + this.cronTasks = new HashMap<Runnable, String>(); + } + this.cronTasks.put(task, cronExpression); + } + + /** + * Add a Runnable task to be triggered with the given fixed delay. + * @see TaskScheduler#scheduleWithFixedDelay(Runnable, long) + */ + public void addFixedDelayTask(Runnable task, long delay) { + if (this.fixedDelayTasks == null) { + this.fixedDelayTasks = new HashMap<Runnable, Long>(); + } + this.fixedDelayTasks.put(task, delay); + } + + /** + * Add a Runnable task to be triggered at the given fixed-rate period. + * @see TaskScheduler#scheduleAtFixedRate(Runnable, long) + */ + public void addFixedRateTask(Runnable task, long period) { + if (this.fixedRateTasks == null) { + this.fixedRateTasks = new HashMap<Runnable, Long>(); + } + this.fixedRateTasks.put(task, period); + } + + /** + * Specify triggered tasks as a Map of Runnables (the tasks) and fixed-delay values. + * @see TaskScheduler#scheduleWithFixedDelay(Runnable, long) + */ + public void setFixedDelayTasks(Map<Runnable, Long> fixedDelayTasks) { + this.fixedDelayTasks = fixedDelayTasks; + } + + + public void afterPropertiesSet() { + if (this.taskScheduler == null) { + this.localExecutor = Executors.newSingleThreadScheduledExecutor(); + this.taskScheduler = new ConcurrentTaskScheduler(this.localExecutor); + } + if (this.triggerTasks != null) { + for (Map.Entry<Runnable, Trigger> entry : this.triggerTasks.entrySet()) { + this.scheduledFutures.add(this.taskScheduler.schedule(entry.getKey(), entry.getValue())); + } + } + if (this.cronTasks != null) { + for (Map.Entry<Runnable, String> entry : this.cronTasks.entrySet()) { + this.scheduledFutures.add(this.taskScheduler.schedule(entry.getKey(), new CronTrigger(entry.getValue()))); + } + } + if (this.fixedRateTasks != null) { + for (Map.Entry<Runnable, Long> entry : this.fixedRateTasks.entrySet()) { + this.scheduledFutures.add(this.taskScheduler.scheduleAtFixedRate(entry.getKey(), entry.getValue())); + } + } + if (this.fixedDelayTasks != null) { + for (Map.Entry<Runnable, Long> entry : this.fixedDelayTasks.entrySet()) { + this.scheduledFutures.add(this.taskScheduler.scheduleWithFixedDelay(entry.getKey(), entry.getValue())); + } + } + } + + + public void destroy() { + for (ScheduledFuture<?> future : this.scheduledFutures) { + future.cancel(true); + } + if (this.localExecutor != null) { + this.localExecutor.shutdownNow(); + } + } + +} diff --git a/org.springframework.context/src/main/java/org/springframework/scheduling/config/package-info.java b/org.springframework.context/src/main/java/org/springframework/scheduling/config/package-info.java index 2ae10a2301f..1f9cc08abe0 100644 --- a/org.springframework.context/src/main/java/org/springframework/scheduling/config/package-info.java +++ b/org.springframework.context/src/main/java/org/springframework/scheduling/config/package-info.java @@ -1,9 +1,9 @@ - -/** - * - * Support package for declarative scheduling configuration, - * with XML schema being the primary configuration format. - * - */ -package org.springframework.scheduling.config; - + +/** + * + * Support package for declarative scheduling configuration, + * with XML schema being the primary configuration format. + * + */ +package org.springframework.scheduling.config; + diff --git a/org.springframework.context/src/main/java/org/springframework/scheduling/support/CronTrigger.java b/org.springframework.context/src/main/java/org/springframework/scheduling/support/CronTrigger.java index 2df21a3348d..a3c8fc8df03 100644 --- a/org.springframework.context/src/main/java/org/springframework/scheduling/support/CronTrigger.java +++ b/org.springframework.context/src/main/java/org/springframework/scheduling/support/CronTrigger.java @@ -1,92 +1,92 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.scheduling.support; - -import java.util.Date; -import java.util.TimeZone; - -import org.springframework.scheduling.Trigger; -import org.springframework.scheduling.TriggerContext; - -/** - * {@link Trigger} implementation for cron expressions. - * Wraps a {@link CronSequenceGenerator}. - * - * @author Juergen Hoeller - * @since 3.0 - * @see CronSequenceGenerator - */ -public class CronTrigger implements Trigger { - - private final CronSequenceGenerator sequenceGenerator; - - - /** - * Build a {@link CronTrigger} from the pattern provided in the default time zone. - * @param cronExpression a space-separated list of time fields, - * following cron expression conventions - */ - public CronTrigger(String cronExpression) { - this(cronExpression, TimeZone.getDefault()); - } - - /** - * Build a {@link CronTrigger} from the pattern provided. - * @param cronExpression a space-separated list of time fields, - * following cron expression conventions - * @param timeZone a time zone in which the trigger times will be generated - */ - public CronTrigger(String cronExpression, TimeZone timeZone) { - this.sequenceGenerator = new CronSequenceGenerator(cronExpression, timeZone); - } - - - public Date nextExecutionTime(TriggerContext triggerContext) { - Date date = triggerContext.lastCompletionTime(); - if (date != null) { - Date scheduled = triggerContext.lastScheduledExecutionTime(); - if (scheduled != null && date.before(scheduled)) { - // Previous task apparently executed too early... - // Let's simply use the last calculated execution time then, - // in order to prevent accidental re-fires in the same second. - date = scheduled; - } - } - else { - date = new Date(); - } - return this.sequenceGenerator.next(date); - } - - - @Override - public boolean equals(Object obj) { - return (this == obj || (obj instanceof CronTrigger && - this.sequenceGenerator.equals(((CronTrigger) obj).sequenceGenerator))); - } - - @Override - public int hashCode() { - return this.sequenceGenerator.hashCode(); - } - - @Override - public String toString() { - return sequenceGenerator.toString(); - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.scheduling.support; + +import java.util.Date; +import java.util.TimeZone; + +import org.springframework.scheduling.Trigger; +import org.springframework.scheduling.TriggerContext; + +/** + * {@link Trigger} implementation for cron expressions. + * Wraps a {@link CronSequenceGenerator}. + * + * @author Juergen Hoeller + * @since 3.0 + * @see CronSequenceGenerator + */ +public class CronTrigger implements Trigger { + + private final CronSequenceGenerator sequenceGenerator; + + + /** + * Build a {@link CronTrigger} from the pattern provided in the default time zone. + * @param cronExpression a space-separated list of time fields, + * following cron expression conventions + */ + public CronTrigger(String cronExpression) { + this(cronExpression, TimeZone.getDefault()); + } + + /** + * Build a {@link CronTrigger} from the pattern provided. + * @param cronExpression a space-separated list of time fields, + * following cron expression conventions + * @param timeZone a time zone in which the trigger times will be generated + */ + public CronTrigger(String cronExpression, TimeZone timeZone) { + this.sequenceGenerator = new CronSequenceGenerator(cronExpression, timeZone); + } + + + public Date nextExecutionTime(TriggerContext triggerContext) { + Date date = triggerContext.lastCompletionTime(); + if (date != null) { + Date scheduled = triggerContext.lastScheduledExecutionTime(); + if (scheduled != null && date.before(scheduled)) { + // Previous task apparently executed too early... + // Let's simply use the last calculated execution time then, + // in order to prevent accidental re-fires in the same second. + date = scheduled; + } + } + else { + date = new Date(); + } + return this.sequenceGenerator.next(date); + } + + + @Override + public boolean equals(Object obj) { + return (this == obj || (obj instanceof CronTrigger && + this.sequenceGenerator.equals(((CronTrigger) obj).sequenceGenerator))); + } + + @Override + public int hashCode() { + return this.sequenceGenerator.hashCode(); + } + + @Override + public String toString() { + return sequenceGenerator.toString(); + } + +} diff --git a/org.springframework.context/src/main/java/org/springframework/scheduling/support/ScheduledMethodRunnable.java b/org.springframework.context/src/main/java/org/springframework/scheduling/support/ScheduledMethodRunnable.java index 207a717a05e..5b7b9350fb4 100644 --- a/org.springframework.context/src/main/java/org/springframework/scheduling/support/ScheduledMethodRunnable.java +++ b/org.springframework.context/src/main/java/org/springframework/scheduling/support/ScheduledMethodRunnable.java @@ -1,74 +1,74 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.scheduling.support; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.UndeclaredThrowableException; - -import org.springframework.util.ReflectionUtils; - -/** - * Variant of {@link MethodInvokingRunnable} meant to be used for processing - * of no-arg scheduled methods. Propagates user exceptions to the caller, - * assuming that an error strategy for Runnables is in place. - * - * @author Juergen Hoeller - * @since 3.0.6 - * @see org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor - */ -public class ScheduledMethodRunnable implements Runnable { - - private final Object target; - - private final Method method; - - - public ScheduledMethodRunnable(Object target, Method method) { - this.target = target; - this.method = method; - } - - public ScheduledMethodRunnable(Object target, String methodName) throws NoSuchMethodException { - this.target = target; - this.method = target.getClass().getMethod(methodName); - } - - - public Object getTarget() { - return this.target; - } - - public Method getMethod() { - return this.method; - } - - - public void run() { - try { - ReflectionUtils.makeAccessible(this.method); - this.method.invoke(this.target); - } - catch (InvocationTargetException ex) { - ReflectionUtils.rethrowRuntimeException(ex.getTargetException()); - } - catch (IllegalAccessException ex) { - throw new UndeclaredThrowableException(ex); - } - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.scheduling.support; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.UndeclaredThrowableException; + +import org.springframework.util.ReflectionUtils; + +/** + * Variant of {@link MethodInvokingRunnable} meant to be used for processing + * of no-arg scheduled methods. Propagates user exceptions to the caller, + * assuming that an error strategy for Runnables is in place. + * + * @author Juergen Hoeller + * @since 3.0.6 + * @see org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor + */ +public class ScheduledMethodRunnable implements Runnable { + + private final Object target; + + private final Method method; + + + public ScheduledMethodRunnable(Object target, Method method) { + this.target = target; + this.method = method; + } + + public ScheduledMethodRunnable(Object target, String methodName) throws NoSuchMethodException { + this.target = target; + this.method = target.getClass().getMethod(methodName); + } + + + public Object getTarget() { + return this.target; + } + + public Method getMethod() { + return this.method; + } + + + public void run() { + try { + ReflectionUtils.makeAccessible(this.method); + this.method.invoke(this.target); + } + catch (InvocationTargetException ex) { + ReflectionUtils.rethrowRuntimeException(ex.getTargetException()); + } + catch (IllegalAccessException ex) { + throw new UndeclaredThrowableException(ex); + } + } + +} diff --git a/org.springframework.context/src/main/java/org/springframework/scheduling/support/SimpleTriggerContext.java b/org.springframework.context/src/main/java/org/springframework/scheduling/support/SimpleTriggerContext.java index 5933bdf4ee1..650d95ea737 100644 --- a/org.springframework.context/src/main/java/org/springframework/scheduling/support/SimpleTriggerContext.java +++ b/org.springframework.context/src/main/java/org/springframework/scheduling/support/SimpleTriggerContext.java @@ -1,63 +1,63 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.scheduling.support; - -import java.util.Date; - -import org.springframework.scheduling.TriggerContext; - -/** - * Simple data holder implementation of the {@link TriggerContext} interface. - * - * @author Juergen Hoeller - * @since 3.0 - */ -public class SimpleTriggerContext implements TriggerContext { - - private volatile Date lastScheduledExecutionTime; - - private volatile Date lastActualExecutionTime; - - private volatile Date lastCompletionTime; - - - /** - * Update this holder's state with the latest time values. - * @param lastScheduledExecutionTime last <i>scheduled</i> execution time - * @param lastActualExecutionTime last <i>actual</i> execution time - * @param lastCompletionTime last completion time - */ - public void update(Date lastScheduledExecutionTime, Date lastActualExecutionTime, Date lastCompletionTime) { - this.lastScheduledExecutionTime = lastScheduledExecutionTime; - this.lastActualExecutionTime = lastActualExecutionTime; - this.lastCompletionTime = lastCompletionTime; - } - - - public Date lastScheduledExecutionTime() { - return this.lastScheduledExecutionTime; - } - - public Date lastActualExecutionTime() { - return this.lastActualExecutionTime; - } - - public Date lastCompletionTime() { - return this.lastCompletionTime; - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.scheduling.support; + +import java.util.Date; + +import org.springframework.scheduling.TriggerContext; + +/** + * Simple data holder implementation of the {@link TriggerContext} interface. + * + * @author Juergen Hoeller + * @since 3.0 + */ +public class SimpleTriggerContext implements TriggerContext { + + private volatile Date lastScheduledExecutionTime; + + private volatile Date lastActualExecutionTime; + + private volatile Date lastCompletionTime; + + + /** + * Update this holder's state with the latest time values. + * @param lastScheduledExecutionTime last <i>scheduled</i> execution time + * @param lastActualExecutionTime last <i>actual</i> execution time + * @param lastCompletionTime last completion time + */ + public void update(Date lastScheduledExecutionTime, Date lastActualExecutionTime, Date lastCompletionTime) { + this.lastScheduledExecutionTime = lastScheduledExecutionTime; + this.lastActualExecutionTime = lastActualExecutionTime; + this.lastCompletionTime = lastCompletionTime; + } + + + public Date lastScheduledExecutionTime() { + return this.lastScheduledExecutionTime; + } + + public Date lastActualExecutionTime() { + return this.lastActualExecutionTime; + } + + public Date lastCompletionTime() { + return this.lastCompletionTime; + } + +} diff --git a/org.springframework.context/src/main/java/org/springframework/validation/annotation/package-info.java b/org.springframework.context/src/main/java/org/springframework/validation/annotation/package-info.java index f13f7981313..2283a3bba63 100644 --- a/org.springframework.context/src/main/java/org/springframework/validation/annotation/package-info.java +++ b/org.springframework.context/src/main/java/org/springframework/validation/annotation/package-info.java @@ -1,8 +1,8 @@ -/** - * Support classes for annotation-based constraint evaluation, - * e.g. using a JSR-303 Bean Validation provider. - * - * <p>Provides an extended variant of JSR-303's <code>@Valid</code>, - * supporting the specification of validation groups. - */ -package org.springframework.validation.annotation; +/** + * Support classes for annotation-based constraint evaluation, + * e.g. using a JSR-303 Bean Validation provider. + * + * <p>Provides an extended variant of JSR-303's <code>@Valid</code>, + * supporting the specification of validation groups. + */ +package org.springframework.validation.annotation; diff --git a/org.springframework.context/src/main/java/org/springframework/validation/beanvalidation/BeanValidationPostProcessor.java b/org.springframework.context/src/main/java/org/springframework/validation/beanvalidation/BeanValidationPostProcessor.java index 3edc4581a49..899207cb5a7 100644 --- a/org.springframework.context/src/main/java/org/springframework/validation/beanvalidation/BeanValidationPostProcessor.java +++ b/org.springframework.context/src/main/java/org/springframework/validation/beanvalidation/BeanValidationPostProcessor.java @@ -1,117 +1,117 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.validation.beanvalidation; - -import java.util.Iterator; -import java.util.Set; -import javax.validation.ConstraintViolation; -import javax.validation.Validation; -import javax.validation.Validator; -import javax.validation.ValidatorFactory; - -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanInitializationException; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.config.BeanPostProcessor; - -/** - * Simple {@link BeanPostProcessor} that checks JSR-303 constraint annotations - * in Spring-managed beans, throwing an initialization exception in case of - * constraint violations right before calling the bean's init method (if any). - * - * @author Juergen Hoeller - * @since 3.0 - */ -public class BeanValidationPostProcessor implements BeanPostProcessor, InitializingBean { - - private Validator validator; - - private boolean afterInitialization = false; - - - /** - * Set the JSR-303 Validator to delegate to for validating beans. - * <p>Default is the default ValidatorFactory's default Validator. - */ - public void setValidator(Validator validator) { - this.validator = validator; - } - - /** - * Set the JSR-303 ValidatorFactory to delegate to for validating beans, - * using its default Validator. - * <p>Default is the default ValidatorFactory's default Validator. - * @see javax.validation.ValidatorFactory#getValidator() - */ - public void setValidatorFactory(ValidatorFactory validatorFactory) { - this.validator = validatorFactory.getValidator(); - } - - /** - * Choose whether to perform validation after bean initialization - * (i.e. after init methods) instead of before (which is the default). - * <p>Default is "false" (before initialization). Switch this to "true" - * (after initialization) if you would like to give init methods a chance - * to populate constrained fields before they get validated. - */ - public void setAfterInitialization(boolean afterInitialization) { - this.afterInitialization = afterInitialization; - } - - public void afterPropertiesSet() { - if (this.validator == null) { - this.validator = Validation.buildDefaultValidatorFactory().getValidator(); - } - } - - - public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { - if (!this.afterInitialization) { - doValidate(bean); - } - return bean; - } - - public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { - if (this.afterInitialization) { - doValidate(bean); - } - return bean; - } - - - /** - * Perform validation of the given bean. - * @param bean the bean instance to validate - * @see javax.validation.Validator#validate - */ - protected void doValidate(Object bean) { - Set<ConstraintViolation<Object>> result = this.validator.validate(bean); - if (!result.isEmpty()) { - StringBuilder sb = new StringBuilder("Bean state is invalid: "); - for (Iterator<ConstraintViolation<Object>> it = result.iterator(); it.hasNext();) { - ConstraintViolation<Object> violation = it.next(); - sb.append(violation.getPropertyPath()).append(" - ").append(violation.getMessage()); - if (it.hasNext()) { - sb.append("; "); - } - } - throw new BeanInitializationException(sb.toString()); - } - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.validation.beanvalidation; + +import java.util.Iterator; +import java.util.Set; +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.Validator; +import javax.validation.ValidatorFactory; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanInitializationException; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.config.BeanPostProcessor; + +/** + * Simple {@link BeanPostProcessor} that checks JSR-303 constraint annotations + * in Spring-managed beans, throwing an initialization exception in case of + * constraint violations right before calling the bean's init method (if any). + * + * @author Juergen Hoeller + * @since 3.0 + */ +public class BeanValidationPostProcessor implements BeanPostProcessor, InitializingBean { + + private Validator validator; + + private boolean afterInitialization = false; + + + /** + * Set the JSR-303 Validator to delegate to for validating beans. + * <p>Default is the default ValidatorFactory's default Validator. + */ + public void setValidator(Validator validator) { + this.validator = validator; + } + + /** + * Set the JSR-303 ValidatorFactory to delegate to for validating beans, + * using its default Validator. + * <p>Default is the default ValidatorFactory's default Validator. + * @see javax.validation.ValidatorFactory#getValidator() + */ + public void setValidatorFactory(ValidatorFactory validatorFactory) { + this.validator = validatorFactory.getValidator(); + } + + /** + * Choose whether to perform validation after bean initialization + * (i.e. after init methods) instead of before (which is the default). + * <p>Default is "false" (before initialization). Switch this to "true" + * (after initialization) if you would like to give init methods a chance + * to populate constrained fields before they get validated. + */ + public void setAfterInitialization(boolean afterInitialization) { + this.afterInitialization = afterInitialization; + } + + public void afterPropertiesSet() { + if (this.validator == null) { + this.validator = Validation.buildDefaultValidatorFactory().getValidator(); + } + } + + + public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { + if (!this.afterInitialization) { + doValidate(bean); + } + return bean; + } + + public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + if (this.afterInitialization) { + doValidate(bean); + } + return bean; + } + + + /** + * Perform validation of the given bean. + * @param bean the bean instance to validate + * @see javax.validation.Validator#validate + */ + protected void doValidate(Object bean) { + Set<ConstraintViolation<Object>> result = this.validator.validate(bean); + if (!result.isEmpty()) { + StringBuilder sb = new StringBuilder("Bean state is invalid: "); + for (Iterator<ConstraintViolation<Object>> it = result.iterator(); it.hasNext();) { + ConstraintViolation<Object> violation = it.next(); + sb.append(violation.getPropertyPath()).append(" - ").append(violation.getMessage()); + if (it.hasNext()) { + sb.append("; "); + } + } + throw new BeanInitializationException(sb.toString()); + } + } + +} diff --git a/org.springframework.context/src/main/java/org/springframework/validation/beanvalidation/CustomValidatorBean.java b/org.springframework.context/src/main/java/org/springframework/validation/beanvalidation/CustomValidatorBean.java index bde13ced82d..2001e78aee3 100644 --- a/org.springframework.context/src/main/java/org/springframework/validation/beanvalidation/CustomValidatorBean.java +++ b/org.springframework.context/src/main/java/org/springframework/validation/beanvalidation/CustomValidatorBean.java @@ -1,86 +1,86 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.validation.beanvalidation; - -import javax.validation.MessageInterpolator; -import javax.validation.TraversableResolver; -import javax.validation.Validation; -import javax.validation.Validator; -import javax.validation.ValidatorContext; -import javax.validation.ValidatorFactory; - -import org.springframework.beans.factory.InitializingBean; - -/** - * Configurable bean class that exposes a specific JSR-303 Validator - * through its original interface as well as through the Spring - * {@link org.springframework.validation.Validator} interface. - * - * @author Juergen Hoeller - * @since 3.0 - */ -public class CustomValidatorBean extends SpringValidatorAdapter implements Validator, InitializingBean { - - private ValidatorFactory validatorFactory; - - private MessageInterpolator messageInterpolator; - - private TraversableResolver traversableResolver; - - - /** - * Set the ValidatorFactory to obtain the target Validator from. - * <p>Default is {@link javax.validation.Validation#buildDefaultValidatorFactory()}. - */ - public void setValidatorFactory(ValidatorFactory validatorFactory) { - this.validatorFactory = validatorFactory; - } - - /** - * Specify a custom MessageInterpolator to use for this Validator. - */ - public void setMessageInterpolator(MessageInterpolator messageInterpolator) { - this.messageInterpolator = messageInterpolator; - } - - /** - * Specify a custom TraversableResolver to use for this Validator. - */ - public void setTraversableResolver(TraversableResolver traversableResolver) { - this.traversableResolver = traversableResolver; - } - - - public void afterPropertiesSet() { - if (this.validatorFactory == null) { - this.validatorFactory = Validation.buildDefaultValidatorFactory(); - } - - ValidatorContext validatorContext = this.validatorFactory.usingContext(); - MessageInterpolator targetInterpolator = this.messageInterpolator; - if (targetInterpolator == null) { - targetInterpolator = this.validatorFactory.getMessageInterpolator(); - } - validatorContext.messageInterpolator(new LocaleContextMessageInterpolator(targetInterpolator)); - if (this.traversableResolver != null) { - validatorContext.traversableResolver(this.traversableResolver); - } - - setTargetValidator(validatorContext.getValidator()); - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.validation.beanvalidation; + +import javax.validation.MessageInterpolator; +import javax.validation.TraversableResolver; +import javax.validation.Validation; +import javax.validation.Validator; +import javax.validation.ValidatorContext; +import javax.validation.ValidatorFactory; + +import org.springframework.beans.factory.InitializingBean; + +/** + * Configurable bean class that exposes a specific JSR-303 Validator + * through its original interface as well as through the Spring + * {@link org.springframework.validation.Validator} interface. + * + * @author Juergen Hoeller + * @since 3.0 + */ +public class CustomValidatorBean extends SpringValidatorAdapter implements Validator, InitializingBean { + + private ValidatorFactory validatorFactory; + + private MessageInterpolator messageInterpolator; + + private TraversableResolver traversableResolver; + + + /** + * Set the ValidatorFactory to obtain the target Validator from. + * <p>Default is {@link javax.validation.Validation#buildDefaultValidatorFactory()}. + */ + public void setValidatorFactory(ValidatorFactory validatorFactory) { + this.validatorFactory = validatorFactory; + } + + /** + * Specify a custom MessageInterpolator to use for this Validator. + */ + public void setMessageInterpolator(MessageInterpolator messageInterpolator) { + this.messageInterpolator = messageInterpolator; + } + + /** + * Specify a custom TraversableResolver to use for this Validator. + */ + public void setTraversableResolver(TraversableResolver traversableResolver) { + this.traversableResolver = traversableResolver; + } + + + public void afterPropertiesSet() { + if (this.validatorFactory == null) { + this.validatorFactory = Validation.buildDefaultValidatorFactory(); + } + + ValidatorContext validatorContext = this.validatorFactory.usingContext(); + MessageInterpolator targetInterpolator = this.messageInterpolator; + if (targetInterpolator == null) { + targetInterpolator = this.validatorFactory.getMessageInterpolator(); + } + validatorContext.messageInterpolator(new LocaleContextMessageInterpolator(targetInterpolator)); + if (this.traversableResolver != null) { + validatorContext.traversableResolver(this.traversableResolver); + } + + setTargetValidator(validatorContext.getValidator()); + } + +} diff --git a/org.springframework.context/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java b/org.springframework.context/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java index de9f3655afa..bc3bc6b2d12 100644 --- a/org.springframework.context/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java +++ b/org.springframework.context/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java @@ -1,257 +1,257 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.validation.beanvalidation; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; -import javax.validation.Configuration; -import javax.validation.ConstraintValidatorFactory; -import javax.validation.MessageInterpolator; -import javax.validation.TraversableResolver; -import javax.validation.Validation; -import javax.validation.Validator; -import javax.validation.ValidatorContext; -import javax.validation.ValidatorFactory; -import javax.validation.spi.ValidationProvider; - -import org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator; - -import org.springframework.beans.factory.InitializingBean; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.context.MessageSource; -import org.springframework.core.io.Resource; -import org.springframework.util.CollectionUtils; - -/** - * This is the central class for <code>javax.validation</code> (JSR-303) setup - * in a Spring application context: It bootstraps a <code>javax.validation.ValidationFactory</code> - * and exposes it through the Spring {@link org.springframework.validation.Validator} interface - * as well as through the JSR-303 {@link javax.validation.Validator} interface and the - * {@link javax.validation.ValidatorFactory} interface itself. - * - * <p>When talking to an instance of this bean through the Spring or JSR-303 Validator interfaces, - * you'll be talking to the default Validator of the underlying ValidatorFactory. This is very - * convenient in that you don't have to perform yet another call on the factory, assuming that - * you will almost always use the default Validator anyway. This can also be injected directly - * into any target dependency of type {@link org.springframework.validation.Validator}! - * - * @author Juergen Hoeller - * @since 3.0 - * @see javax.validation.ValidatorFactory - * @see javax.validation.Validator - * @see javax.validation.Validation#buildDefaultValidatorFactory() - * @see javax.validation.ValidatorFactory#getValidator() - */ -public class LocalValidatorFactoryBean extends SpringValidatorAdapter - implements ValidatorFactory, ApplicationContextAware, InitializingBean { - - @SuppressWarnings("rawtypes") - private Class providerClass; - - private MessageInterpolator messageInterpolator; - - private TraversableResolver traversableResolver; - - private ConstraintValidatorFactory constraintValidatorFactory; - - private Resource[] mappingLocations; - - private final Map<String, String> validationPropertyMap = new HashMap<String, String>(); - - private ApplicationContext applicationContext; - - private ValidatorFactory validatorFactory; - - - /** - * Specify the desired provider class, if any. - * <p>If not specified, JSR-303's default search mechanism will be used. - * @see javax.validation.Validation#byProvider(Class) - * @see javax.validation.Validation#byDefaultProvider() - */ - @SuppressWarnings("rawtypes") - public void setProviderClass(Class<? extends ValidationProvider> providerClass) { - this.providerClass = providerClass; - } - - /** - * Specify a custom MessageInterpolator to use for this ValidatorFactory - * and its exposed default Validator. - */ - public void setMessageInterpolator(MessageInterpolator messageInterpolator) { - this.messageInterpolator = messageInterpolator; - } - - /** - * Specify a custom Spring MessageSource for resolving validation messages, - * instead of relying on JSR-303's default "ValidationMessages.properties" bundle - * in the classpath. This may refer to a Spring context's shared "messageSource" bean, - * or to some special MessageSource setup for validation purposes only. - * <p><b>NOTE:</b> This feature requires Hibernate Validator 4.1 or higher on the classpath. - * You may nevertheless use a different validation provider but Hibernate Validator's - * {@link ResourceBundleMessageInterpolator} class must be accessible during configuration. - * <p>Specify either this property or {@link #setMessageInterpolator "messageInterpolator"}, - * not both. If you would like to build a custom MessageInterpolator, consider deriving from - * Hibernate Validator's {@link ResourceBundleMessageInterpolator} and passing in a - * Spring {@link MessageSourceResourceBundleLocator} when constructing your interpolator. - * @see ResourceBundleMessageInterpolator - * @see MessageSourceResourceBundleLocator - */ - public void setValidationMessageSource(MessageSource messageSource) { - this.messageInterpolator = HibernateValidatorDelegate.buildMessageInterpolator(messageSource); - } - - /** - * Specify a custom TraversableResolver to use for this ValidatorFactory - * and its exposed default Validator. - */ - public void setTraversableResolver(TraversableResolver traversableResolver) { - this.traversableResolver = traversableResolver; - } - - /** - * Specify a custom ConstraintValidatorFactory to use for this ValidatorFactory. - * <p>Default is a {@link SpringConstraintValidatorFactory}, delegating to the - * containing ApplicationContext for creating autowired ConstraintValidator instances. - */ - public void setConstraintValidatorFactory(ConstraintValidatorFactory constraintValidatorFactory) { - this.constraintValidatorFactory = constraintValidatorFactory; - } - - /** - * Specify resource locations to load XML constraint mapping files from, if any. - */ - public void setMappingLocations(Resource[] mappingLocations) { - this.mappingLocations = mappingLocations; - } - - /** - * Specify bean validation properties to be passed to the validation provider. - * <p>Can be populated with a String "value" (parsed via PropertiesEditor) - * or a "props" element in XML bean definitions. - * @see javax.validation.Configuration#addProperty(String, String) - */ - public void setValidationProperties(Properties jpaProperties) { - CollectionUtils.mergePropertiesIntoMap(jpaProperties, this.validationPropertyMap); - } - - /** - * Specify bean validation properties to be passed to the validation provider as a Map. - * <p>Can be populated with a "map" or "props" element in XML bean definitions. - * @see javax.validation.Configuration#addProperty(String, String) - */ - public void setValidationPropertyMap(Map<String, String> validationProperties) { - if (validationProperties != null) { - this.validationPropertyMap.putAll(validationProperties); - } - } - - /** - * Allow Map access to the bean validation properties to be passed to the validation provider, - * with the option to add or override specific entries. - * <p>Useful for specifying entries directly, for example via "validationPropertyMap[myKey]". - */ - public Map<String, String> getValidationPropertyMap() { - return this.validationPropertyMap; - } - - public void setApplicationContext(ApplicationContext applicationContext) { - this.applicationContext = applicationContext; - } - - - @SuppressWarnings("unchecked") - public void afterPropertiesSet() { - @SuppressWarnings("rawtypes") - Configuration configuration = (this.providerClass != null ? - Validation.byProvider(this.providerClass).configure() : - Validation.byDefaultProvider().configure()); - - MessageInterpolator targetInterpolator = this.messageInterpolator; - if (targetInterpolator == null) { - targetInterpolator = configuration.getDefaultMessageInterpolator(); - } - configuration.messageInterpolator(new LocaleContextMessageInterpolator(targetInterpolator)); - - if (this.traversableResolver != null) { - configuration.traversableResolver(this.traversableResolver); - } - - ConstraintValidatorFactory targetConstraintValidatorFactory = this.constraintValidatorFactory; - if (targetConstraintValidatorFactory == null && this.applicationContext != null) { - targetConstraintValidatorFactory = - new SpringConstraintValidatorFactory(this.applicationContext.getAutowireCapableBeanFactory()); - } - if (targetConstraintValidatorFactory != null) { - configuration.constraintValidatorFactory(targetConstraintValidatorFactory); - } - - if (this.mappingLocations != null) { - for (Resource location : this.mappingLocations) { - try { - configuration.addMapping(location.getInputStream()); - } - catch (IOException ex) { - throw new IllegalStateException("Cannot read mapping resource: " + location); - } - } - } - - for (Map.Entry<String, String> entry : this.validationPropertyMap.entrySet()) { - configuration.addProperty(entry.getKey(), entry.getValue()); - } - - this.validatorFactory = configuration.buildValidatorFactory(); - setTargetValidator(this.validatorFactory.getValidator()); - } - - - public Validator getValidator() { - return this.validatorFactory.getValidator(); - } - - public ValidatorContext usingContext() { - return this.validatorFactory.usingContext(); - } - - public MessageInterpolator getMessageInterpolator() { - return this.validatorFactory.getMessageInterpolator(); - } - - public TraversableResolver getTraversableResolver() { - return this.validatorFactory.getTraversableResolver(); - } - - public ConstraintValidatorFactory getConstraintValidatorFactory() { - return this.validatorFactory.getConstraintValidatorFactory(); - } - - - /** - * Inner class to avoid a hard-coded Hibernate Validator 4.1 dependency. - */ - private static class HibernateValidatorDelegate { - - public static MessageInterpolator buildMessageInterpolator(MessageSource messageSource) { - return new ResourceBundleMessageInterpolator(new MessageSourceResourceBundleLocator(messageSource)); - } - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.validation.beanvalidation; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import javax.validation.Configuration; +import javax.validation.ConstraintValidatorFactory; +import javax.validation.MessageInterpolator; +import javax.validation.TraversableResolver; +import javax.validation.Validation; +import javax.validation.Validator; +import javax.validation.ValidatorContext; +import javax.validation.ValidatorFactory; +import javax.validation.spi.ValidationProvider; + +import org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator; + +import org.springframework.beans.factory.InitializingBean; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.context.MessageSource; +import org.springframework.core.io.Resource; +import org.springframework.util.CollectionUtils; + +/** + * This is the central class for <code>javax.validation</code> (JSR-303) setup + * in a Spring application context: It bootstraps a <code>javax.validation.ValidationFactory</code> + * and exposes it through the Spring {@link org.springframework.validation.Validator} interface + * as well as through the JSR-303 {@link javax.validation.Validator} interface and the + * {@link javax.validation.ValidatorFactory} interface itself. + * + * <p>When talking to an instance of this bean through the Spring or JSR-303 Validator interfaces, + * you'll be talking to the default Validator of the underlying ValidatorFactory. This is very + * convenient in that you don't have to perform yet another call on the factory, assuming that + * you will almost always use the default Validator anyway. This can also be injected directly + * into any target dependency of type {@link org.springframework.validation.Validator}! + * + * @author Juergen Hoeller + * @since 3.0 + * @see javax.validation.ValidatorFactory + * @see javax.validation.Validator + * @see javax.validation.Validation#buildDefaultValidatorFactory() + * @see javax.validation.ValidatorFactory#getValidator() + */ +public class LocalValidatorFactoryBean extends SpringValidatorAdapter + implements ValidatorFactory, ApplicationContextAware, InitializingBean { + + @SuppressWarnings("rawtypes") + private Class providerClass; + + private MessageInterpolator messageInterpolator; + + private TraversableResolver traversableResolver; + + private ConstraintValidatorFactory constraintValidatorFactory; + + private Resource[] mappingLocations; + + private final Map<String, String> validationPropertyMap = new HashMap<String, String>(); + + private ApplicationContext applicationContext; + + private ValidatorFactory validatorFactory; + + + /** + * Specify the desired provider class, if any. + * <p>If not specified, JSR-303's default search mechanism will be used. + * @see javax.validation.Validation#byProvider(Class) + * @see javax.validation.Validation#byDefaultProvider() + */ + @SuppressWarnings("rawtypes") + public void setProviderClass(Class<? extends ValidationProvider> providerClass) { + this.providerClass = providerClass; + } + + /** + * Specify a custom MessageInterpolator to use for this ValidatorFactory + * and its exposed default Validator. + */ + public void setMessageInterpolator(MessageInterpolator messageInterpolator) { + this.messageInterpolator = messageInterpolator; + } + + /** + * Specify a custom Spring MessageSource for resolving validation messages, + * instead of relying on JSR-303's default "ValidationMessages.properties" bundle + * in the classpath. This may refer to a Spring context's shared "messageSource" bean, + * or to some special MessageSource setup for validation purposes only. + * <p><b>NOTE:</b> This feature requires Hibernate Validator 4.1 or higher on the classpath. + * You may nevertheless use a different validation provider but Hibernate Validator's + * {@link ResourceBundleMessageInterpolator} class must be accessible during configuration. + * <p>Specify either this property or {@link #setMessageInterpolator "messageInterpolator"}, + * not both. If you would like to build a custom MessageInterpolator, consider deriving from + * Hibernate Validator's {@link ResourceBundleMessageInterpolator} and passing in a + * Spring {@link MessageSourceResourceBundleLocator} when constructing your interpolator. + * @see ResourceBundleMessageInterpolator + * @see MessageSourceResourceBundleLocator + */ + public void setValidationMessageSource(MessageSource messageSource) { + this.messageInterpolator = HibernateValidatorDelegate.buildMessageInterpolator(messageSource); + } + + /** + * Specify a custom TraversableResolver to use for this ValidatorFactory + * and its exposed default Validator. + */ + public void setTraversableResolver(TraversableResolver traversableResolver) { + this.traversableResolver = traversableResolver; + } + + /** + * Specify a custom ConstraintValidatorFactory to use for this ValidatorFactory. + * <p>Default is a {@link SpringConstraintValidatorFactory}, delegating to the + * containing ApplicationContext for creating autowired ConstraintValidator instances. + */ + public void setConstraintValidatorFactory(ConstraintValidatorFactory constraintValidatorFactory) { + this.constraintValidatorFactory = constraintValidatorFactory; + } + + /** + * Specify resource locations to load XML constraint mapping files from, if any. + */ + public void setMappingLocations(Resource[] mappingLocations) { + this.mappingLocations = mappingLocations; + } + + /** + * Specify bean validation properties to be passed to the validation provider. + * <p>Can be populated with a String "value" (parsed via PropertiesEditor) + * or a "props" element in XML bean definitions. + * @see javax.validation.Configuration#addProperty(String, String) + */ + public void setValidationProperties(Properties jpaProperties) { + CollectionUtils.mergePropertiesIntoMap(jpaProperties, this.validationPropertyMap); + } + + /** + * Specify bean validation properties to be passed to the validation provider as a Map. + * <p>Can be populated with a "map" or "props" element in XML bean definitions. + * @see javax.validation.Configuration#addProperty(String, String) + */ + public void setValidationPropertyMap(Map<String, String> validationProperties) { + if (validationProperties != null) { + this.validationPropertyMap.putAll(validationProperties); + } + } + + /** + * Allow Map access to the bean validation properties to be passed to the validation provider, + * with the option to add or override specific entries. + * <p>Useful for specifying entries directly, for example via "validationPropertyMap[myKey]". + */ + public Map<String, String> getValidationPropertyMap() { + return this.validationPropertyMap; + } + + public void setApplicationContext(ApplicationContext applicationContext) { + this.applicationContext = applicationContext; + } + + + @SuppressWarnings("unchecked") + public void afterPropertiesSet() { + @SuppressWarnings("rawtypes") + Configuration configuration = (this.providerClass != null ? + Validation.byProvider(this.providerClass).configure() : + Validation.byDefaultProvider().configure()); + + MessageInterpolator targetInterpolator = this.messageInterpolator; + if (targetInterpolator == null) { + targetInterpolator = configuration.getDefaultMessageInterpolator(); + } + configuration.messageInterpolator(new LocaleContextMessageInterpolator(targetInterpolator)); + + if (this.traversableResolver != null) { + configuration.traversableResolver(this.traversableResolver); + } + + ConstraintValidatorFactory targetConstraintValidatorFactory = this.constraintValidatorFactory; + if (targetConstraintValidatorFactory == null && this.applicationContext != null) { + targetConstraintValidatorFactory = + new SpringConstraintValidatorFactory(this.applicationContext.getAutowireCapableBeanFactory()); + } + if (targetConstraintValidatorFactory != null) { + configuration.constraintValidatorFactory(targetConstraintValidatorFactory); + } + + if (this.mappingLocations != null) { + for (Resource location : this.mappingLocations) { + try { + configuration.addMapping(location.getInputStream()); + } + catch (IOException ex) { + throw new IllegalStateException("Cannot read mapping resource: " + location); + } + } + } + + for (Map.Entry<String, String> entry : this.validationPropertyMap.entrySet()) { + configuration.addProperty(entry.getKey(), entry.getValue()); + } + + this.validatorFactory = configuration.buildValidatorFactory(); + setTargetValidator(this.validatorFactory.getValidator()); + } + + + public Validator getValidator() { + return this.validatorFactory.getValidator(); + } + + public ValidatorContext usingContext() { + return this.validatorFactory.usingContext(); + } + + public MessageInterpolator getMessageInterpolator() { + return this.validatorFactory.getMessageInterpolator(); + } + + public TraversableResolver getTraversableResolver() { + return this.validatorFactory.getTraversableResolver(); + } + + public ConstraintValidatorFactory getConstraintValidatorFactory() { + return this.validatorFactory.getConstraintValidatorFactory(); + } + + + /** + * Inner class to avoid a hard-coded Hibernate Validator 4.1 dependency. + */ + private static class HibernateValidatorDelegate { + + public static MessageInterpolator buildMessageInterpolator(MessageSource messageSource) { + return new ResourceBundleMessageInterpolator(new MessageSourceResourceBundleLocator(messageSource)); + } + } + +} diff --git a/org.springframework.context/src/main/java/org/springframework/validation/beanvalidation/LocaleContextMessageInterpolator.java b/org.springframework.context/src/main/java/org/springframework/validation/beanvalidation/LocaleContextMessageInterpolator.java index 1bab6a4aa7a..06c897fc16f 100644 --- a/org.springframework.context/src/main/java/org/springframework/validation/beanvalidation/LocaleContextMessageInterpolator.java +++ b/org.springframework.context/src/main/java/org/springframework/validation/beanvalidation/LocaleContextMessageInterpolator.java @@ -1,56 +1,56 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.validation.beanvalidation; - -import java.util.Locale; -import javax.validation.MessageInterpolator; - -import org.springframework.context.i18n.LocaleContextHolder; -import org.springframework.util.Assert; - -/** - * Delegates to a target {@link MessageInterpolator} implementation but enforces Spring's - * managed Locale. Typically used to wrap the validation provider's default interpolator. - * - * @author Juergen Hoeller - * @since 3.0 - * @see org.springframework.context.i18n.LocaleContextHolder#getLocale() - */ -public class LocaleContextMessageInterpolator implements MessageInterpolator { - - private final MessageInterpolator targetInterpolator; - - - /** - * Create a new LocaleContextMessageInterpolator, wrapping the given target interpolator. - * @param targetInterpolator the target MessageInterpolator to wrap - */ - public LocaleContextMessageInterpolator(MessageInterpolator targetInterpolator) { - Assert.notNull(targetInterpolator, "Target MessageInterpolator must not be null"); - this.targetInterpolator = targetInterpolator; - } - - - public String interpolate(String message, Context context) { - return this.targetInterpolator.interpolate(message, context, LocaleContextHolder.getLocale()); - } - - public String interpolate(String message, Context context, Locale locale) { - return this.targetInterpolator.interpolate(message, context, locale); - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.validation.beanvalidation; + +import java.util.Locale; +import javax.validation.MessageInterpolator; + +import org.springframework.context.i18n.LocaleContextHolder; +import org.springframework.util.Assert; + +/** + * Delegates to a target {@link MessageInterpolator} implementation but enforces Spring's + * managed Locale. Typically used to wrap the validation provider's default interpolator. + * + * @author Juergen Hoeller + * @since 3.0 + * @see org.springframework.context.i18n.LocaleContextHolder#getLocale() + */ +public class LocaleContextMessageInterpolator implements MessageInterpolator { + + private final MessageInterpolator targetInterpolator; + + + /** + * Create a new LocaleContextMessageInterpolator, wrapping the given target interpolator. + * @param targetInterpolator the target MessageInterpolator to wrap + */ + public LocaleContextMessageInterpolator(MessageInterpolator targetInterpolator) { + Assert.notNull(targetInterpolator, "Target MessageInterpolator must not be null"); + this.targetInterpolator = targetInterpolator; + } + + + public String interpolate(String message, Context context) { + return this.targetInterpolator.interpolate(message, context, LocaleContextHolder.getLocale()); + } + + public String interpolate(String message, Context context, Locale locale) { + return this.targetInterpolator.interpolate(message, context, locale); + } + +} diff --git a/org.springframework.context/src/main/java/org/springframework/validation/beanvalidation/MessageSourceResourceBundleLocator.java b/org.springframework.context/src/main/java/org/springframework/validation/beanvalidation/MessageSourceResourceBundleLocator.java index cf9177c9ed8..83c538e38cd 100644 --- a/org.springframework.context/src/main/java/org/springframework/validation/beanvalidation/MessageSourceResourceBundleLocator.java +++ b/org.springframework.context/src/main/java/org/springframework/validation/beanvalidation/MessageSourceResourceBundleLocator.java @@ -1,55 +1,55 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.validation.beanvalidation; - -import java.util.Locale; -import java.util.ResourceBundle; - -import org.hibernate.validator.resourceloading.ResourceBundleLocator; - -import org.springframework.context.MessageSource; -import org.springframework.context.support.MessageSourceResourceBundle; -import org.springframework.util.Assert; - -/** - * Implementation of Hibernate Validator 4.1's {@link ResourceBundleLocator} interface, - * exposing a Spring {@link MessageSource} as localized {@link MessageSourceResourceBundle}. - * - * @author Juergen Hoeller - * @since 3.0.4 - * @see ResourceBundleLocator - * @see MessageSource - * @see MessageSourceResourceBundle - */ -public class MessageSourceResourceBundleLocator implements ResourceBundleLocator { - - private final MessageSource messageSource; - - /** - * Build a MessageSourceResourceBundleLocator for the given MessageSource. - * @param messageSource the Spring MessageSource to wrap - */ - public MessageSourceResourceBundleLocator(MessageSource messageSource) { - Assert.notNull(messageSource, "MessageSource must not be null"); - this.messageSource = messageSource; - } - - public ResourceBundle getResourceBundle(Locale locale) { - return new MessageSourceResourceBundle(this.messageSource, locale); - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.validation.beanvalidation; + +import java.util.Locale; +import java.util.ResourceBundle; + +import org.hibernate.validator.resourceloading.ResourceBundleLocator; + +import org.springframework.context.MessageSource; +import org.springframework.context.support.MessageSourceResourceBundle; +import org.springframework.util.Assert; + +/** + * Implementation of Hibernate Validator 4.1's {@link ResourceBundleLocator} interface, + * exposing a Spring {@link MessageSource} as localized {@link MessageSourceResourceBundle}. + * + * @author Juergen Hoeller + * @since 3.0.4 + * @see ResourceBundleLocator + * @see MessageSource + * @see MessageSourceResourceBundle + */ +public class MessageSourceResourceBundleLocator implements ResourceBundleLocator { + + private final MessageSource messageSource; + + /** + * Build a MessageSourceResourceBundleLocator for the given MessageSource. + * @param messageSource the Spring MessageSource to wrap + */ + public MessageSourceResourceBundleLocator(MessageSource messageSource) { + Assert.notNull(messageSource, "MessageSource must not be null"); + this.messageSource = messageSource; + } + + public ResourceBundle getResourceBundle(Locale locale) { + return new MessageSourceResourceBundle(this.messageSource, locale); + } + +} diff --git a/org.springframework.context/src/main/java/org/springframework/validation/beanvalidation/SpringConstraintValidatorFactory.java b/org.springframework.context/src/main/java/org/springframework/validation/beanvalidation/SpringConstraintValidatorFactory.java index 0fc183316f5..e619287cff6 100644 --- a/org.springframework.context/src/main/java/org/springframework/validation/beanvalidation/SpringConstraintValidatorFactory.java +++ b/org.springframework.context/src/main/java/org/springframework/validation/beanvalidation/SpringConstraintValidatorFactory.java @@ -1,53 +1,53 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.validation.beanvalidation; - -import javax.validation.ConstraintValidator; -import javax.validation.ConstraintValidatorFactory; - -import org.springframework.beans.factory.config.AutowireCapableBeanFactory; -import org.springframework.util.Assert; - -/** - * JSR-303 {@link ConstraintValidatorFactory} implementation that delegates to a - * Spring BeanFactory for creating autowired {@link ConstraintValidator} instances. - * - * @author Juergen Hoeller - * @since 3.0 - * @see org.springframework.beans.factory.config.AutowireCapableBeanFactory#createBean(Class) - * @see org.springframework.context.ApplicationContext#getAutowireCapableBeanFactory() - */ -public class SpringConstraintValidatorFactory implements ConstraintValidatorFactory { - - private final AutowireCapableBeanFactory beanFactory; - - - /** - * Create a new SpringConstraintValidatorFactory for the given BeanFactory. - * @param beanFactory the target BeanFactory - */ - public SpringConstraintValidatorFactory(AutowireCapableBeanFactory beanFactory) { - Assert.notNull(beanFactory, "BeanFactory must not be null"); - this.beanFactory = beanFactory; - } - - - public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> key) { - return this.beanFactory.createBean(key); - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.validation.beanvalidation; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorFactory; + +import org.springframework.beans.factory.config.AutowireCapableBeanFactory; +import org.springframework.util.Assert; + +/** + * JSR-303 {@link ConstraintValidatorFactory} implementation that delegates to a + * Spring BeanFactory for creating autowired {@link ConstraintValidator} instances. + * + * @author Juergen Hoeller + * @since 3.0 + * @see org.springframework.beans.factory.config.AutowireCapableBeanFactory#createBean(Class) + * @see org.springframework.context.ApplicationContext#getAutowireCapableBeanFactory() + */ +public class SpringConstraintValidatorFactory implements ConstraintValidatorFactory { + + private final AutowireCapableBeanFactory beanFactory; + + + /** + * Create a new SpringConstraintValidatorFactory for the given BeanFactory. + * @param beanFactory the target BeanFactory + */ + public SpringConstraintValidatorFactory(AutowireCapableBeanFactory beanFactory) { + Assert.notNull(beanFactory, "BeanFactory must not be null"); + this.beanFactory = beanFactory; + } + + + public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> key) { + return this.beanFactory.createBean(key); + } + +} diff --git a/org.springframework.context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java b/org.springframework.context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java index 08ef9b89bde..91fd75ab60e 100644 --- a/org.springframework.context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java +++ b/org.springframework.context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java @@ -1,216 +1,216 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.validation.beanvalidation; - -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; -import javax.validation.ConstraintViolation; -import javax.validation.metadata.BeanDescriptor; -import javax.validation.metadata.ConstraintDescriptor; - -import org.springframework.beans.NotReadablePropertyException; -import org.springframework.context.support.DefaultMessageSourceResolvable; -import org.springframework.util.Assert; -import org.springframework.validation.BindingResult; -import org.springframework.validation.Errors; -import org.springframework.validation.FieldError; -import org.springframework.validation.ObjectError; -import org.springframework.validation.SmartValidator; - -/** - * Adapter that takes a JSR-303 <code>javax.validator.Validator</code> - * and exposes it as a Spring {@link org.springframework.validation.Validator} - * while also exposing the original JSR-303 Validator interface itself. - * - * <p>Can be used as a programmatic wrapper. Also serves as base class for - * {@link CustomValidatorBean} and {@link LocalValidatorFactoryBean}. - * - * @author Juergen Hoeller - * @since 3.0 - */ -public class SpringValidatorAdapter implements SmartValidator, javax.validation.Validator { - - private static final Set<String> internalAnnotationAttributes = new HashSet<String>(3); - - static { - internalAnnotationAttributes.add("message"); - internalAnnotationAttributes.add("groups"); - internalAnnotationAttributes.add("payload"); - } - - private javax.validation.Validator targetValidator; - - - /** - * Create a new SpringValidatorAdapter for the given JSR-303 Validator. - * @param targetValidator the JSR-303 Validator to wrap - */ - public SpringValidatorAdapter(javax.validation.Validator targetValidator) { - Assert.notNull(targetValidator, "Target Validator must not be null"); - this.targetValidator = targetValidator; - } - - SpringValidatorAdapter() { - } - - void setTargetValidator(javax.validation.Validator targetValidator) { - this.targetValidator = targetValidator; - } - - - //--------------------------------------------------------------------- - // Implementation of Spring Validator interface - //--------------------------------------------------------------------- - - public boolean supports(Class<?> clazz) { - return true; - } - - public void validate(Object target, Errors errors) { - processConstraintViolations(this.targetValidator.validate(target), errors); - } - - public void validate(Object target, Errors errors, Object... validationHints) { - Set<Class> groups = new LinkedHashSet<Class>(); - if (validationHints != null) { - for (Object hint : validationHints) { - if (hint instanceof Class) { - groups.add((Class) hint); - } - } - } - processConstraintViolations(this.targetValidator.validate(target, groups.toArray(new Class[groups.size()])), errors); - } - - /** - * Process the given JSR-303 ConstraintViolations, adding corresponding errors to - * the provided Spring {@link Errors} object. - * @param violations the JSR-303 ConstraintViolation results - * @param errors the Spring errors object to register to - */ - protected void processConstraintViolations(Set<ConstraintViolation<Object>> violations, Errors errors) { - for (ConstraintViolation<Object> violation : violations) { - String field = violation.getPropertyPath().toString(); - FieldError fieldError = errors.getFieldError(field); - if (fieldError == null || !fieldError.isBindingFailure()) { - try { - String errorCode = violation.getConstraintDescriptor().getAnnotation().annotationType().getSimpleName(); - Object[] errorArgs = getArgumentsForConstraint(errors.getObjectName(), field, violation.getConstraintDescriptor()); - if (errors instanceof BindingResult) { - // can do custom FieldError registration with invalid value from ConstraintViolation, - // as necessary for Hibernate Validator compatibility (non-indexed set path in field) - BindingResult bindingResult = (BindingResult) errors; - String[] errorCodes = bindingResult.resolveMessageCodes(errorCode, field); - String nestedField = bindingResult.getNestedPath() + field; - ObjectError error; - if ("".equals(nestedField)) { - error = new ObjectError( - errors.getObjectName(), errorCodes, errorArgs, violation.getMessage()); - } - else { - Object invalidValue = violation.getInvalidValue(); - if (!"".equals(field) && invalidValue == violation.getLeafBean()) { - // bean constraint with property path: retrieve the actual property value - invalidValue = bindingResult.getRawFieldValue(field); - } - error = new FieldError( - errors.getObjectName(), nestedField, invalidValue, false, - errorCodes, errorArgs, violation.getMessage()); - } - bindingResult.addError(error); - } - else { - // got no BindingResult - can only do standard rejectValue call - // with automatic extraction of the current field value - errors.rejectValue(field, errorCode, errorArgs, violation.getMessage()); - } - } - catch (NotReadablePropertyException ex) { - throw new IllegalStateException("JSR-303 validated property '" + field + - "' does not have a corresponding accessor for Spring data binding - " + - "check your DataBinder's configuration (bean property versus direct field access)", ex); - } - } - } - } - - /** - * Return FieldError arguments for a validation error on the given field. - * Invoked for each violated constraint. - * <p>The default implementation returns a first argument indicating the field name - * (of type DefaultMessageSourceResolvable, with "objectName.field" and "field" as codes). - * Afterwards, it adds all actual constraint annotation attributes (i.e. excluding - * "message", "groups" and "payload") in alphabetical order of their attribute names. - * <p>Can be overridden to e.g. add further attributes from the constraint descriptor. - * @param objectName the name of the target object - * @param field the field that caused the binding error - * @param descriptor the JSR-303 constraint descriptor - * @return the Object array that represents the FieldError arguments - * @see org.springframework.validation.FieldError#getArguments - * @see org.springframework.context.support.DefaultMessageSourceResolvable - * @see org.springframework.validation.DefaultBindingErrorProcessor#getArgumentsForBindError - */ - protected Object[] getArgumentsForConstraint(String objectName, String field, ConstraintDescriptor<?> descriptor) { - List<Object> arguments = new LinkedList<Object>(); - String[] codes = new String[] {objectName + Errors.NESTED_PATH_SEPARATOR + field, field}; - arguments.add(new DefaultMessageSourceResolvable(codes, field)); - // Using a TreeMap for alphabetical ordering of attribute names - Map<String, Object> attributesToExpose = new TreeMap<String, Object>(); - for (Map.Entry<String, Object> entry : descriptor.getAttributes().entrySet()) { - String attributeName = entry.getKey(); - Object attributeValue = entry.getValue(); - if (!internalAnnotationAttributes.contains(attributeName)) { - attributesToExpose.put(attributeName, attributeValue); - } - } - arguments.addAll(attributesToExpose.values()); - return arguments.toArray(new Object[arguments.size()]); - } - - - //--------------------------------------------------------------------- - // Implementation of JSR-303 Validator interface - //--------------------------------------------------------------------- - - public <T> Set<ConstraintViolation<T>> validate(T object, Class<?>... groups) { - return this.targetValidator.validate(object, groups); - } - - public <T> Set<ConstraintViolation<T>> validateProperty(T object, String propertyName, Class<?>... groups) { - return this.targetValidator.validateProperty(object, propertyName, groups); - } - - public <T> Set<ConstraintViolation<T>> validateValue( - Class<T> beanType, String propertyName, Object value, Class<?>... groups) { - - return this.targetValidator.validateValue(beanType, propertyName, value, groups); - } - - public BeanDescriptor getConstraintsForClass(Class<?> clazz) { - return this.targetValidator.getConstraintsForClass(clazz); - } - - public <T> T unwrap(Class<T> type) { - return this.targetValidator.unwrap(type); - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.validation.beanvalidation; + +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import javax.validation.ConstraintViolation; +import javax.validation.metadata.BeanDescriptor; +import javax.validation.metadata.ConstraintDescriptor; + +import org.springframework.beans.NotReadablePropertyException; +import org.springframework.context.support.DefaultMessageSourceResolvable; +import org.springframework.util.Assert; +import org.springframework.validation.BindingResult; +import org.springframework.validation.Errors; +import org.springframework.validation.FieldError; +import org.springframework.validation.ObjectError; +import org.springframework.validation.SmartValidator; + +/** + * Adapter that takes a JSR-303 <code>javax.validator.Validator</code> + * and exposes it as a Spring {@link org.springframework.validation.Validator} + * while also exposing the original JSR-303 Validator interface itself. + * + * <p>Can be used as a programmatic wrapper. Also serves as base class for + * {@link CustomValidatorBean} and {@link LocalValidatorFactoryBean}. + * + * @author Juergen Hoeller + * @since 3.0 + */ +public class SpringValidatorAdapter implements SmartValidator, javax.validation.Validator { + + private static final Set<String> internalAnnotationAttributes = new HashSet<String>(3); + + static { + internalAnnotationAttributes.add("message"); + internalAnnotationAttributes.add("groups"); + internalAnnotationAttributes.add("payload"); + } + + private javax.validation.Validator targetValidator; + + + /** + * Create a new SpringValidatorAdapter for the given JSR-303 Validator. + * @param targetValidator the JSR-303 Validator to wrap + */ + public SpringValidatorAdapter(javax.validation.Validator targetValidator) { + Assert.notNull(targetValidator, "Target Validator must not be null"); + this.targetValidator = targetValidator; + } + + SpringValidatorAdapter() { + } + + void setTargetValidator(javax.validation.Validator targetValidator) { + this.targetValidator = targetValidator; + } + + + //--------------------------------------------------------------------- + // Implementation of Spring Validator interface + //--------------------------------------------------------------------- + + public boolean supports(Class<?> clazz) { + return true; + } + + public void validate(Object target, Errors errors) { + processConstraintViolations(this.targetValidator.validate(target), errors); + } + + public void validate(Object target, Errors errors, Object... validationHints) { + Set<Class> groups = new LinkedHashSet<Class>(); + if (validationHints != null) { + for (Object hint : validationHints) { + if (hint instanceof Class) { + groups.add((Class) hint); + } + } + } + processConstraintViolations(this.targetValidator.validate(target, groups.toArray(new Class[groups.size()])), errors); + } + + /** + * Process the given JSR-303 ConstraintViolations, adding corresponding errors to + * the provided Spring {@link Errors} object. + * @param violations the JSR-303 ConstraintViolation results + * @param errors the Spring errors object to register to + */ + protected void processConstraintViolations(Set<ConstraintViolation<Object>> violations, Errors errors) { + for (ConstraintViolation<Object> violation : violations) { + String field = violation.getPropertyPath().toString(); + FieldError fieldError = errors.getFieldError(field); + if (fieldError == null || !fieldError.isBindingFailure()) { + try { + String errorCode = violation.getConstraintDescriptor().getAnnotation().annotationType().getSimpleName(); + Object[] errorArgs = getArgumentsForConstraint(errors.getObjectName(), field, violation.getConstraintDescriptor()); + if (errors instanceof BindingResult) { + // can do custom FieldError registration with invalid value from ConstraintViolation, + // as necessary for Hibernate Validator compatibility (non-indexed set path in field) + BindingResult bindingResult = (BindingResult) errors; + String[] errorCodes = bindingResult.resolveMessageCodes(errorCode, field); + String nestedField = bindingResult.getNestedPath() + field; + ObjectError error; + if ("".equals(nestedField)) { + error = new ObjectError( + errors.getObjectName(), errorCodes, errorArgs, violation.getMessage()); + } + else { + Object invalidValue = violation.getInvalidValue(); + if (!"".equals(field) && invalidValue == violation.getLeafBean()) { + // bean constraint with property path: retrieve the actual property value + invalidValue = bindingResult.getRawFieldValue(field); + } + error = new FieldError( + errors.getObjectName(), nestedField, invalidValue, false, + errorCodes, errorArgs, violation.getMessage()); + } + bindingResult.addError(error); + } + else { + // got no BindingResult - can only do standard rejectValue call + // with automatic extraction of the current field value + errors.rejectValue(field, errorCode, errorArgs, violation.getMessage()); + } + } + catch (NotReadablePropertyException ex) { + throw new IllegalStateException("JSR-303 validated property '" + field + + "' does not have a corresponding accessor for Spring data binding - " + + "check your DataBinder's configuration (bean property versus direct field access)", ex); + } + } + } + } + + /** + * Return FieldError arguments for a validation error on the given field. + * Invoked for each violated constraint. + * <p>The default implementation returns a first argument indicating the field name + * (of type DefaultMessageSourceResolvable, with "objectName.field" and "field" as codes). + * Afterwards, it adds all actual constraint annotation attributes (i.e. excluding + * "message", "groups" and "payload") in alphabetical order of their attribute names. + * <p>Can be overridden to e.g. add further attributes from the constraint descriptor. + * @param objectName the name of the target object + * @param field the field that caused the binding error + * @param descriptor the JSR-303 constraint descriptor + * @return the Object array that represents the FieldError arguments + * @see org.springframework.validation.FieldError#getArguments + * @see org.springframework.context.support.DefaultMessageSourceResolvable + * @see org.springframework.validation.DefaultBindingErrorProcessor#getArgumentsForBindError + */ + protected Object[] getArgumentsForConstraint(String objectName, String field, ConstraintDescriptor<?> descriptor) { + List<Object> arguments = new LinkedList<Object>(); + String[] codes = new String[] {objectName + Errors.NESTED_PATH_SEPARATOR + field, field}; + arguments.add(new DefaultMessageSourceResolvable(codes, field)); + // Using a TreeMap for alphabetical ordering of attribute names + Map<String, Object> attributesToExpose = new TreeMap<String, Object>(); + for (Map.Entry<String, Object> entry : descriptor.getAttributes().entrySet()) { + String attributeName = entry.getKey(); + Object attributeValue = entry.getValue(); + if (!internalAnnotationAttributes.contains(attributeName)) { + attributesToExpose.put(attributeName, attributeValue); + } + } + arguments.addAll(attributesToExpose.values()); + return arguments.toArray(new Object[arguments.size()]); + } + + + //--------------------------------------------------------------------- + // Implementation of JSR-303 Validator interface + //--------------------------------------------------------------------- + + public <T> Set<ConstraintViolation<T>> validate(T object, Class<?>... groups) { + return this.targetValidator.validate(object, groups); + } + + public <T> Set<ConstraintViolation<T>> validateProperty(T object, String propertyName, Class<?>... groups) { + return this.targetValidator.validateProperty(object, propertyName, groups); + } + + public <T> Set<ConstraintViolation<T>> validateValue( + Class<T> beanType, String propertyName, Object value, Class<?>... groups) { + + return this.targetValidator.validateValue(beanType, propertyName, value, groups); + } + + public BeanDescriptor getConstraintsForClass(Class<?> clazz) { + return this.targetValidator.getConstraintsForClass(clazz); + } + + public <T> T unwrap(Class<T> type) { + return this.targetValidator.unwrap(type); + } + +} diff --git a/org.springframework.context/src/main/java/org/springframework/validation/beanvalidation/package-info.java b/org.springframework.context/src/main/java/org/springframework/validation/beanvalidation/package-info.java index f9c8354a401..7961d3ab945 100644 --- a/org.springframework.context/src/main/java/org/springframework/validation/beanvalidation/package-info.java +++ b/org.springframework.context/src/main/java/org/springframework/validation/beanvalidation/package-info.java @@ -1,11 +1,11 @@ -/** - * Support classes for integrating a JSR-303 Bean Validation provider - * (such as Hibernate Validator 4.0) into a Spring ApplicationContext - * and in particular with Spring's data binding and validation APIs. - * - * <p>The central class is {@link - * org.springframework.validation.beanvalidation.LocalValidatorFactoryBean} - * which defines a shared ValidatorFactory/Validator setup for availability - * to other Spring components. - */ -package org.springframework.validation.beanvalidation; +/** + * Support classes for integrating a JSR-303 Bean Validation provider + * (such as Hibernate Validator 4.0) into a Spring ApplicationContext + * and in particular with Spring's data binding and validation APIs. + * + * <p>The central class is {@link + * org.springframework.validation.beanvalidation.LocalValidatorFactoryBean} + * which defines a shared ValidatorFactory/Validator setup for availability + * to other Spring components. + */ +package org.springframework.validation.beanvalidation; diff --git a/org.springframework.context/src/test/java/org/springframework/cache/NoOpCacheManagerTests.java b/org.springframework.context/src/test/java/org/springframework/cache/NoOpCacheManagerTests.java index 2de234ebe5b..79b39b60a67 100644 --- a/org.springframework.context/src/test/java/org/springframework/cache/NoOpCacheManagerTests.java +++ b/org.springframework.context/src/test/java/org/springframework/cache/NoOpCacheManagerTests.java @@ -1,61 +1,61 @@ -/* - * Copyright 2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cache; - -import static org.junit.Assert.*; - -import java.util.UUID; - -import org.junit.Before; -import org.junit.Test; -import org.springframework.cache.support.NoOpCacheManager; - -public class NoOpCacheManagerTests { - - private CacheManager manager; - - @Before - public void setup() { - manager = new NoOpCacheManager(); - } - - @Test - public void testGetCache() throws Exception { - Cache cache = manager.getCache("bucket"); - assertNotNull(cache); - assertSame(cache, manager.getCache("bucket")); - } - - @Test - public void testNoOpCache() throws Exception { - String name = UUID.randomUUID().toString(); - Cache cache = manager.getCache(name); - assertEquals(name, cache.getName()); - Object key = new Object(); - cache.put(key, new Object()); - assertNull(cache.get(key)); - assertNull(cache.getNativeCache()); - } - - @Test - public void testCacheName() throws Exception { - String name = "bucket"; - assertFalse(manager.getCacheNames().contains(name)); - manager.getCache(name); - assertTrue(manager.getCacheNames().contains(name)); - } -} +/* + * Copyright 2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cache; + +import static org.junit.Assert.*; + +import java.util.UUID; + +import org.junit.Before; +import org.junit.Test; +import org.springframework.cache.support.NoOpCacheManager; + +public class NoOpCacheManagerTests { + + private CacheManager manager; + + @Before + public void setup() { + manager = new NoOpCacheManager(); + } + + @Test + public void testGetCache() throws Exception { + Cache cache = manager.getCache("bucket"); + assertNotNull(cache); + assertSame(cache, manager.getCache("bucket")); + } + + @Test + public void testNoOpCache() throws Exception { + String name = UUID.randomUUID().toString(); + Cache cache = manager.getCache(name); + assertEquals(name, cache.getName()); + Object key = new Object(); + cache.put(key, new Object()); + assertNull(cache.get(key)); + assertNull(cache.getNativeCache()); + } + + @Test + public void testCacheName() throws Exception { + String name = "bucket"; + assertFalse(manager.getCacheNames().contains(name)); + manager.getCache(name); + assertTrue(manager.getCacheNames().contains(name)); + } +} diff --git a/org.springframework.context/src/test/java/org/springframework/cache/concurrent/ConcurrentCacheTests.java b/org.springframework.context/src/test/java/org/springframework/cache/concurrent/ConcurrentCacheTests.java index 0669bc0c080..88ae4bfa889 100644 --- a/org.springframework.context/src/test/java/org/springframework/cache/concurrent/ConcurrentCacheTests.java +++ b/org.springframework.context/src/test/java/org/springframework/cache/concurrent/ConcurrentCacheTests.java @@ -1,39 +1,39 @@ -/* - * Copyright 2010-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cache.concurrent; - -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -import org.springframework.cache.Cache; -import org.springframework.cache.vendor.AbstractNativeCacheTests; - -/** - * @author Costin Leau - */ -public class ConcurrentCacheTests extends AbstractNativeCacheTests<ConcurrentMap<Object, Object>> { - - @Override - protected Cache createCache(ConcurrentMap<Object, Object> nativeCache) { - return new ConcurrentMapCache(CACHE_NAME, nativeCache, true); - } - - @Override - protected ConcurrentMap<Object, Object> createNativeCache() throws Exception { - return new ConcurrentHashMap<Object, Object>(); - } -} +/* + * Copyright 2010-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cache.concurrent; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import org.springframework.cache.Cache; +import org.springframework.cache.vendor.AbstractNativeCacheTests; + +/** + * @author Costin Leau + */ +public class ConcurrentCacheTests extends AbstractNativeCacheTests<ConcurrentMap<Object, Object>> { + + @Override + protected Cache createCache(ConcurrentMap<Object, Object> nativeCache) { + return new ConcurrentMapCache(CACHE_NAME, nativeCache, true); + } + + @Override + protected ConcurrentMap<Object, Object> createNativeCache() throws Exception { + return new ConcurrentHashMap<Object, Object>(); + } +} diff --git a/org.springframework.context/src/test/java/org/springframework/cache/concurrent/ConcurrentMapCacheManagerTests.java b/org.springframework.context/src/test/java/org/springframework/cache/concurrent/ConcurrentMapCacheManagerTests.java index 69b66d41ccb..cc0c9630704 100644 --- a/org.springframework.context/src/test/java/org/springframework/cache/concurrent/ConcurrentMapCacheManagerTests.java +++ b/org.springframework.context/src/test/java/org/springframework/cache/concurrent/ConcurrentMapCacheManagerTests.java @@ -1,63 +1,63 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cache.concurrent; - -import org.junit.Test; - -import org.springframework.cache.Cache; -import org.springframework.cache.CacheManager; - -import static org.junit.Assert.*; - -/** - * @author Juergen Hoeller - */ -public class ConcurrentMapCacheManagerTests { - - @Test - public void testDynamicMode() { - CacheManager cm = new ConcurrentMapCacheManager(); - Cache cache1 = cm.getCache("c1"); - assertTrue(cache1 instanceof ConcurrentMapCache); - Cache cache1again = cm.getCache("c1"); - assertSame(cache1again, cache1); - Cache cache2 = cm.getCache("c2"); - assertTrue(cache2 instanceof ConcurrentMapCache); - Cache cache2again = cm.getCache("c2"); - assertSame(cache2again, cache2); - Cache cache3 = cm.getCache("c3"); - assertTrue(cache3 instanceof ConcurrentMapCache); - Cache cache3again = cm.getCache("c3"); - assertSame(cache3again, cache3); - } - - @Test - public void testStaticMode() { - ConcurrentMapCacheManager cm = new ConcurrentMapCacheManager("c1", "c2"); - Cache cache1 = cm.getCache("c1"); - assertTrue(cache1 instanceof ConcurrentMapCache); - Cache cache1again = cm.getCache("c1"); - assertSame(cache1again, cache1); - Cache cache2 = cm.getCache("c2"); - assertTrue(cache2 instanceof ConcurrentMapCache); - Cache cache2again = cm.getCache("c2"); - assertSame(cache2again, cache2); - Cache cache3 = cm.getCache("c3"); - assertNull(cache3); - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cache.concurrent; + +import org.junit.Test; + +import org.springframework.cache.Cache; +import org.springframework.cache.CacheManager; + +import static org.junit.Assert.*; + +/** + * @author Juergen Hoeller + */ +public class ConcurrentMapCacheManagerTests { + + @Test + public void testDynamicMode() { + CacheManager cm = new ConcurrentMapCacheManager(); + Cache cache1 = cm.getCache("c1"); + assertTrue(cache1 instanceof ConcurrentMapCache); + Cache cache1again = cm.getCache("c1"); + assertSame(cache1again, cache1); + Cache cache2 = cm.getCache("c2"); + assertTrue(cache2 instanceof ConcurrentMapCache); + Cache cache2again = cm.getCache("c2"); + assertSame(cache2again, cache2); + Cache cache3 = cm.getCache("c3"); + assertTrue(cache3 instanceof ConcurrentMapCache); + Cache cache3again = cm.getCache("c3"); + assertSame(cache3again, cache3); + } + + @Test + public void testStaticMode() { + ConcurrentMapCacheManager cm = new ConcurrentMapCacheManager("c1", "c2"); + Cache cache1 = cm.getCache("c1"); + assertTrue(cache1 instanceof ConcurrentMapCache); + Cache cache1again = cm.getCache("c1"); + assertSame(cache1again, cache1); + Cache cache2 = cm.getCache("c2"); + assertTrue(cache2 instanceof ConcurrentMapCache); + Cache cache2again = cm.getCache("c2"); + assertSame(cache2again, cache2); + Cache cache3 = cm.getCache("c3"); + assertNull(cache3); + } + +} diff --git a/org.springframework.context/src/test/java/org/springframework/cache/config/AbstractAnnotationTests.java b/org.springframework.context/src/test/java/org/springframework/cache/config/AbstractAnnotationTests.java index cfc661281fd..4bc0c888b31 100644 --- a/org.springframework.context/src/test/java/org/springframework/cache/config/AbstractAnnotationTests.java +++ b/org.springframework.context/src/test/java/org/springframework/cache/config/AbstractAnnotationTests.java @@ -1,621 +1,621 @@ -/* - * Copyright 2010-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cache.config; - -import static org.junit.Assert.*; - -import java.util.Collection; -import java.util.UUID; - -import org.junit.Before; -import org.junit.Test; -import org.springframework.aop.framework.AopProxyUtils; -import org.springframework.cache.Cache; -import org.springframework.cache.CacheManager; -import org.springframework.context.ApplicationContext; - -/** - * Abstract annotation test (containing several reusable methods). - * - * @author Costin Leau - * @author Chris Beams - */ -public abstract class AbstractAnnotationTests { - - protected ApplicationContext ctx; - - protected CacheableService<?> cs; - - protected CacheableService<?> ccs; - - protected CacheManager cm; - - /** @return a refreshed application context */ - protected abstract ApplicationContext getApplicationContext(); - - @Before - public void setup() { - ctx = getApplicationContext(); - cs = ctx.getBean("service", CacheableService.class); - ccs = ctx.getBean("classService", CacheableService.class); - cm = ctx.getBean(CacheManager.class); - Collection<String> cn = cm.getCacheNames(); - assertTrue(cn.contains("default")); - assertTrue(cn.contains("secondary")); - assertTrue(cn.contains("primary")); - } - - public void testCacheable(CacheableService<?> service) throws Exception { - Object o1 = new Object(); - - Object r1 = service.cache(o1); - Object r2 = service.cache(o1); - Object r3 = service.cache(o1); - - assertSame(r1, r2); - assertSame(r1, r3); - } - - public void testEvict(CacheableService<?> service) throws Exception { - Object o1 = new Object(); - - Object r1 = service.cache(o1); - Object r2 = service.cache(o1); - - assertSame(r1, r2); - service.invalidate(o1); - Object r3 = service.cache(o1); - Object r4 = service.cache(o1); - assertNotSame(r1, r3); - assertSame(r3, r4); - } - - public void testEvictEarly(CacheableService<?> service) throws Exception { - Object o1 = new Object(); - - Object r1 = service.cache(o1); - Object r2 = service.cache(o1); - - assertSame(r1, r2); - try { - service.evictEarly(o1); - } catch (RuntimeException ex) { - // expected - } - - Object r3 = service.cache(o1); - Object r4 = service.cache(o1); - assertNotSame(r1, r3); - assertSame(r3, r4); - } - - public void testEvictException(CacheableService<?> service) throws Exception { - Object o1 = new Object(); - - Object r1 = service.cache(o1); - Object r2 = service.cache(o1); - - assertSame(r1, r2); - try { - service.evictWithException(o1); - } catch (RuntimeException ex) { - // expected - } - // exception occurred, eviction skipped, data should still be in the cache - Object r3 = service.cache(o1); - assertSame(r1, r3); - } - - public void testEvictWKey(CacheableService<?> service) throws Exception { - Object o1 = new Object(); - - Object r1 = service.cache(o1); - Object r2 = service.cache(o1); - - assertSame(r1, r2); - service.evict(o1, null); - Object r3 = service.cache(o1); - Object r4 = service.cache(o1); - assertNotSame(r1, r3); - assertSame(r3, r4); - } - - public void testEvictWKeyEarly(CacheableService<?> service) throws Exception { - Object o1 = new Object(); - - Object r1 = service.cache(o1); - Object r2 = service.cache(o1); - - assertSame(r1, r2); - - try { - service.invalidateEarly(o1, null); - } catch (Exception ex) { - // expected - } - Object r3 = service.cache(o1); - Object r4 = service.cache(o1); - assertNotSame(r1, r3); - assertSame(r3, r4); - } - - public void testEvictAll(CacheableService<?> service) throws Exception { - Object o1 = new Object(); - - Object r1 = service.cache(o1); - Object r2 = service.cache(o1); - - Object o2 = new Object(); - Object r10 = service.cache(o2); - - assertSame(r1, r2); - assertNotSame(r1, r10); - service.evictAll(new Object()); - Cache cache = cm.getCache("default"); - assertNull(cache.get(o1)); - assertNull(cache.get(o2)); - - Object r3 = service.cache(o1); - Object r4 = service.cache(o1); - assertNotSame(r1, r3); - assertSame(r3, r4); - } - - public void testConditionalExpression(CacheableService<?> service) throws Exception { - Object r1 = service.conditional(4); - Object r2 = service.conditional(4); - - assertNotSame(r1, r2); - - Object r3 = service.conditional(3); - Object r4 = service.conditional(3); - - assertSame(r3, r4); - } - - public void testKeyExpression(CacheableService<?> service) throws Exception { - Object r1 = service.key(5, 1); - Object r2 = service.key(5, 2); - - assertSame(r1, r2); - - Object r3 = service.key(1, 5); - Object r4 = service.key(2, 5); - - assertNotSame(r3, r4); - } - - public void testNullValue(CacheableService<?> service) throws Exception { - Object key = new Object(); - assertNull(service.nullValue(key)); - int nr = service.nullInvocations().intValue(); - assertNull(service.nullValue(key)); - assertEquals(nr, service.nullInvocations().intValue()); - assertNull(service.nullValue(new Object())); - assertEquals(nr + 1, service.nullInvocations().intValue()); - } - - public void testMethodName(CacheableService<?> service, String keyName) throws Exception { - Object key = new Object(); - Object r1 = service.name(key); - assertSame(r1, service.name(key)); - Cache cache = cm.getCache("default"); - // assert the method name is used - assertNotNull(cache.get(keyName)); - } - - public void testRootVars(CacheableService<?> service) { - Object key = new Object(); - Object r1 = service.rootVars(key); - assertSame(r1, service.rootVars(key)); - Cache cache = cm.getCache("default"); - // assert the method name is used - String expectedKey = "rootVarsrootVars" + AopProxyUtils.ultimateTargetClass(service) + service; - assertNotNull(cache.get(expectedKey)); - } - - public void testCheckedThrowable(CacheableService<?> service) throws Exception { - String arg = UUID.randomUUID().toString(); - try { - service.throwChecked(arg); - fail("Excepted exception"); - } catch (Exception ex) { - assertEquals(arg, ex.getMessage()); - } - } - - public void testUncheckedThrowable(CacheableService<?> service) throws Exception { - try { - service.throwUnchecked(Long.valueOf(1)); - fail("Excepted exception"); - } catch (RuntimeException ex) { - assertTrue("Excepted different exception type and got " + ex.getClass(), - ex instanceof UnsupportedOperationException); - // expected - } - } - - public void testNullArg(CacheableService<?> service) { - Object r1 = service.cache(null); - assertSame(r1, service.cache(null)); - } - - public void testCacheUpdate(CacheableService<?> service) { - Object o = new Object(); - Cache cache = cm.getCache("default"); - assertNull(cache.get(o)); - Object r1 = service.update(o); - assertSame(r1, cache.get(o).get()); - - o = new Object(); - assertNull(cache.get(o)); - Object r2 = service.update(o); - assertSame(r2, cache.get(o).get()); - } - - public void testConditionalCacheUpdate(CacheableService<?> service) { - Integer one = Integer.valueOf(1); - Integer three = Integer.valueOf(3); - - Cache cache = cm.getCache("default"); - assertEquals(one, Integer.valueOf(service.conditionalUpdate(one).toString())); - assertNull(cache.get(one)); - - assertEquals(three, Integer.valueOf(service.conditionalUpdate(three).toString())); - assertEquals(three, Integer.valueOf(cache.get(three).get().toString())); - } - - public void testMultiCache(CacheableService<?> service) { - Object o1 = new Object(); - Object o2 = new Object(); - - Cache primary = cm.getCache("primary"); - Cache secondary = cm.getCache("secondary"); - - assertNull(primary.get(o1)); - assertNull(secondary.get(o1)); - Object r1 = service.multiCache(o1); - assertSame(r1, primary.get(o1).get()); - assertSame(r1, secondary.get(o1).get()); - - Object r2 = service.multiCache(o1); - Object r3 = service.multiCache(o1); - - assertSame(r1, r2); - assertSame(r1, r3); - - assertNull(primary.get(o2)); - assertNull(secondary.get(o2)); - Object r4 = service.multiCache(o2); - assertSame(r4, primary.get(o2).get()); - assertSame(r4, secondary.get(o2).get()); - } - - public void testMultiEvict(CacheableService<?> service) { - Object o1 = new Object(); - Object o2 = o1.toString() + "A"; - - - Object r1 = service.multiCache(o1); - Object r2 = service.multiCache(o1); - - Cache primary = cm.getCache("primary"); - Cache secondary = cm.getCache("secondary"); - - primary.put(o2, o2); - assertSame(r1, r2); - assertSame(r1, primary.get(o1).get()); - assertSame(r1, secondary.get(o1).get()); - - service.multiEvict(o1); - assertNull(primary.get(o1)); - assertNull(secondary.get(o1)); - assertNull(primary.get(o2)); - - Object r3 = service.multiCache(o1); - Object r4 = service.multiCache(o1); - assertNotSame(r1, r3); - assertSame(r3, r4); - - assertSame(r3, primary.get(o1).get()); - assertSame(r4, secondary.get(o1).get()); - } - - public void testMultiPut(CacheableService<?> service) { - Object o = Integer.valueOf(1); - - Cache primary = cm.getCache("primary"); - Cache secondary = cm.getCache("secondary"); - - assertNull(primary.get(o)); - assertNull(secondary.get(o)); - Object r1 = service.multiUpdate(o); - assertSame(r1, primary.get(o).get()); - assertSame(r1, secondary.get(o).get()); - - o = Integer.valueOf(2); - assertNull(primary.get(o)); - assertNull(secondary.get(o)); - Object r2 = service.multiUpdate(o); - assertSame(r2, primary.get(o).get()); - assertSame(r2, secondary.get(o).get()); - } - - public void testMultiCacheAndEvict(CacheableService<?> service) { - String methodName = "multiCacheAndEvict"; - - Cache primary = cm.getCache("primary"); - Cache secondary = cm.getCache("secondary"); - Object key = Integer.valueOf(1); - - secondary.put(key, key); - - assertNull(secondary.get(methodName)); - assertSame(key, secondary.get(key).get()); - - Object r1 = service.multiCacheAndEvict(key); - assertSame(r1, service.multiCacheAndEvict(key)); - - // assert the method name is used - assertSame(r1, primary.get(methodName).get()); - assertNull(secondary.get(methodName)); - assertNull(secondary.get(key)); - } - - public void testMultiConditionalCacheAndEvict(CacheableService<?> service) { - Cache primary = cm.getCache("primary"); - Cache secondary = cm.getCache("secondary"); - Object key = Integer.valueOf(1); - - secondary.put(key, key); - - assertNull(primary.get(key)); - assertSame(key, secondary.get(key).get()); - - Object r1 = service.multiConditionalCacheAndEvict(key); - Object r3 = service.multiConditionalCacheAndEvict(key); - - assertTrue(!r1.equals(r3)); - assertNull(primary.get(key)); - - Object key2 = Integer.valueOf(3); - Object r2 = service.multiConditionalCacheAndEvict(key2); - assertSame(r2, service.multiConditionalCacheAndEvict(key2)); - - // assert the method name is used - assertSame(r2, primary.get(key2).get()); - assertNull(secondary.get(key2)); - } - - @Test - public void testCacheable() throws Exception { - testCacheable(cs); - } - - @Test - public void testInvalidate() throws Exception { - testEvict(cs); - } - - @Test - public void testEarlyInvalidate() throws Exception { - testEvictEarly(cs); - } - - @Test - public void testEvictWithException() throws Exception { - testEvictException(cs); - } - - @Test - public void testEvictAll() throws Exception { - testEvictAll(cs); - } - - @Test - public void testInvalidateWithKey() throws Exception { - testEvictWKey(cs); - } - - @Test - public void testEarlyInvalidateWithKey() throws Exception { - testEvictWKeyEarly(cs); - } - - @Test - public void testConditionalExpression() throws Exception { - testConditionalExpression(cs); - } - - @Test - public void testKeyExpression() throws Exception { - testKeyExpression(cs); - } - - @Test - public void testClassCacheCacheable() throws Exception { - testCacheable(ccs); - } - - @Test - public void testClassCacheInvalidate() throws Exception { - testEvict(ccs); - } - - @Test - public void testClassEarlyInvalidate() throws Exception { - testEvictEarly(ccs); - } - - @Test - public void testClassEvictAll() throws Exception { - testEvictAll(ccs); - } - - @Test - public void testClassEvictWithException() throws Exception { - testEvictException(ccs); - } - - @Test - public void testClassCacheInvalidateWKey() throws Exception { - testEvictWKey(ccs); - } - - @Test - public void testClassEarlyInvalidateWithKey() throws Exception { - testEvictWKeyEarly(ccs); - } - - @Test - public void testNullValue() throws Exception { - testNullValue(cs); - } - - @Test - public void testClassNullValue() throws Exception { - Object key = new Object(); - assertNull(ccs.nullValue(key)); - int nr = ccs.nullInvocations().intValue(); - assertNull(ccs.nullValue(key)); - assertEquals(nr, ccs.nullInvocations().intValue()); - assertNull(ccs.nullValue(new Object())); - // the check method is also cached - assertEquals(nr, ccs.nullInvocations().intValue()); - assertEquals(nr + 1, AnnotatedClassCacheableService.nullInvocations.intValue()); - } - - @Test - public void testMethodName() throws Exception { - testMethodName(cs, "name"); - } - - @Test - public void testClassMethodName() throws Exception { - testMethodName(ccs, "namedefault"); - } - - @Test - public void testRootVars() throws Exception { - testRootVars(cs); - } - - @Test - public void testClassRootVars() throws Exception { - testRootVars(ccs); - } - - @Test - public void testNullArg() throws Exception { - testNullArg(cs); - } - - @Test - public void testClassNullArg() throws Exception { - testNullArg(ccs); - } - - @Test - public void testCheckedException() throws Exception { - testCheckedThrowable(cs); - } - - @Test - public void testClassCheckedException() throws Exception { - testCheckedThrowable(ccs); - } - - @Test - public void testUncheckedException() throws Exception { - testUncheckedThrowable(cs); - } - - @Test - public void testClassUncheckedException() throws Exception { - testUncheckedThrowable(ccs); - } - - @Test - public void testUpdate() { - testCacheUpdate(cs); - } - - @Test - public void testClassUpdate() { - testCacheUpdate(ccs); - } - - @Test - public void testConditionalUpdate() { - testConditionalCacheUpdate(cs); - } - - @Test - public void testClassConditionalUpdate() { - testConditionalCacheUpdate(ccs); - } - - @Test - public void testMultiCache() { - testMultiCache(cs); - } - - @Test - public void testClassMultiCache() { - testMultiCache(ccs); - } - - @Test - public void testMultiEvict() { - testMultiEvict(cs); - } - - @Test - public void testClassMultiEvict() { - testMultiEvict(ccs); - } - - @Test - public void testMultiPut() { - testMultiPut(cs); - } - - @Test - public void testClassMultiPut() { - testMultiPut(ccs); - } - - @Test - public void testMultiCacheAndEvict() { - testMultiCacheAndEvict(cs); - } - - @Test - public void testClassMultiCacheAndEvict() { - testMultiCacheAndEvict(ccs); - } - - @Test - public void testMultiConditionalCacheAndEvict() { - testMultiConditionalCacheAndEvict(cs); - } - - @Test - public void testClassMultiConditionalCacheAndEvict() { - testMultiConditionalCacheAndEvict(ccs); - } +/* + * Copyright 2010-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cache.config; + +import static org.junit.Assert.*; + +import java.util.Collection; +import java.util.UUID; + +import org.junit.Before; +import org.junit.Test; +import org.springframework.aop.framework.AopProxyUtils; +import org.springframework.cache.Cache; +import org.springframework.cache.CacheManager; +import org.springframework.context.ApplicationContext; + +/** + * Abstract annotation test (containing several reusable methods). + * + * @author Costin Leau + * @author Chris Beams + */ +public abstract class AbstractAnnotationTests { + + protected ApplicationContext ctx; + + protected CacheableService<?> cs; + + protected CacheableService<?> ccs; + + protected CacheManager cm; + + /** @return a refreshed application context */ + protected abstract ApplicationContext getApplicationContext(); + + @Before + public void setup() { + ctx = getApplicationContext(); + cs = ctx.getBean("service", CacheableService.class); + ccs = ctx.getBean("classService", CacheableService.class); + cm = ctx.getBean(CacheManager.class); + Collection<String> cn = cm.getCacheNames(); + assertTrue(cn.contains("default")); + assertTrue(cn.contains("secondary")); + assertTrue(cn.contains("primary")); + } + + public void testCacheable(CacheableService<?> service) throws Exception { + Object o1 = new Object(); + + Object r1 = service.cache(o1); + Object r2 = service.cache(o1); + Object r3 = service.cache(o1); + + assertSame(r1, r2); + assertSame(r1, r3); + } + + public void testEvict(CacheableService<?> service) throws Exception { + Object o1 = new Object(); + + Object r1 = service.cache(o1); + Object r2 = service.cache(o1); + + assertSame(r1, r2); + service.invalidate(o1); + Object r3 = service.cache(o1); + Object r4 = service.cache(o1); + assertNotSame(r1, r3); + assertSame(r3, r4); + } + + public void testEvictEarly(CacheableService<?> service) throws Exception { + Object o1 = new Object(); + + Object r1 = service.cache(o1); + Object r2 = service.cache(o1); + + assertSame(r1, r2); + try { + service.evictEarly(o1); + } catch (RuntimeException ex) { + // expected + } + + Object r3 = service.cache(o1); + Object r4 = service.cache(o1); + assertNotSame(r1, r3); + assertSame(r3, r4); + } + + public void testEvictException(CacheableService<?> service) throws Exception { + Object o1 = new Object(); + + Object r1 = service.cache(o1); + Object r2 = service.cache(o1); + + assertSame(r1, r2); + try { + service.evictWithException(o1); + } catch (RuntimeException ex) { + // expected + } + // exception occurred, eviction skipped, data should still be in the cache + Object r3 = service.cache(o1); + assertSame(r1, r3); + } + + public void testEvictWKey(CacheableService<?> service) throws Exception { + Object o1 = new Object(); + + Object r1 = service.cache(o1); + Object r2 = service.cache(o1); + + assertSame(r1, r2); + service.evict(o1, null); + Object r3 = service.cache(o1); + Object r4 = service.cache(o1); + assertNotSame(r1, r3); + assertSame(r3, r4); + } + + public void testEvictWKeyEarly(CacheableService<?> service) throws Exception { + Object o1 = new Object(); + + Object r1 = service.cache(o1); + Object r2 = service.cache(o1); + + assertSame(r1, r2); + + try { + service.invalidateEarly(o1, null); + } catch (Exception ex) { + // expected + } + Object r3 = service.cache(o1); + Object r4 = service.cache(o1); + assertNotSame(r1, r3); + assertSame(r3, r4); + } + + public void testEvictAll(CacheableService<?> service) throws Exception { + Object o1 = new Object(); + + Object r1 = service.cache(o1); + Object r2 = service.cache(o1); + + Object o2 = new Object(); + Object r10 = service.cache(o2); + + assertSame(r1, r2); + assertNotSame(r1, r10); + service.evictAll(new Object()); + Cache cache = cm.getCache("default"); + assertNull(cache.get(o1)); + assertNull(cache.get(o2)); + + Object r3 = service.cache(o1); + Object r4 = service.cache(o1); + assertNotSame(r1, r3); + assertSame(r3, r4); + } + + public void testConditionalExpression(CacheableService<?> service) throws Exception { + Object r1 = service.conditional(4); + Object r2 = service.conditional(4); + + assertNotSame(r1, r2); + + Object r3 = service.conditional(3); + Object r4 = service.conditional(3); + + assertSame(r3, r4); + } + + public void testKeyExpression(CacheableService<?> service) throws Exception { + Object r1 = service.key(5, 1); + Object r2 = service.key(5, 2); + + assertSame(r1, r2); + + Object r3 = service.key(1, 5); + Object r4 = service.key(2, 5); + + assertNotSame(r3, r4); + } + + public void testNullValue(CacheableService<?> service) throws Exception { + Object key = new Object(); + assertNull(service.nullValue(key)); + int nr = service.nullInvocations().intValue(); + assertNull(service.nullValue(key)); + assertEquals(nr, service.nullInvocations().intValue()); + assertNull(service.nullValue(new Object())); + assertEquals(nr + 1, service.nullInvocations().intValue()); + } + + public void testMethodName(CacheableService<?> service, String keyName) throws Exception { + Object key = new Object(); + Object r1 = service.name(key); + assertSame(r1, service.name(key)); + Cache cache = cm.getCache("default"); + // assert the method name is used + assertNotNull(cache.get(keyName)); + } + + public void testRootVars(CacheableService<?> service) { + Object key = new Object(); + Object r1 = service.rootVars(key); + assertSame(r1, service.rootVars(key)); + Cache cache = cm.getCache("default"); + // assert the method name is used + String expectedKey = "rootVarsrootVars" + AopProxyUtils.ultimateTargetClass(service) + service; + assertNotNull(cache.get(expectedKey)); + } + + public void testCheckedThrowable(CacheableService<?> service) throws Exception { + String arg = UUID.randomUUID().toString(); + try { + service.throwChecked(arg); + fail("Excepted exception"); + } catch (Exception ex) { + assertEquals(arg, ex.getMessage()); + } + } + + public void testUncheckedThrowable(CacheableService<?> service) throws Exception { + try { + service.throwUnchecked(Long.valueOf(1)); + fail("Excepted exception"); + } catch (RuntimeException ex) { + assertTrue("Excepted different exception type and got " + ex.getClass(), + ex instanceof UnsupportedOperationException); + // expected + } + } + + public void testNullArg(CacheableService<?> service) { + Object r1 = service.cache(null); + assertSame(r1, service.cache(null)); + } + + public void testCacheUpdate(CacheableService<?> service) { + Object o = new Object(); + Cache cache = cm.getCache("default"); + assertNull(cache.get(o)); + Object r1 = service.update(o); + assertSame(r1, cache.get(o).get()); + + o = new Object(); + assertNull(cache.get(o)); + Object r2 = service.update(o); + assertSame(r2, cache.get(o).get()); + } + + public void testConditionalCacheUpdate(CacheableService<?> service) { + Integer one = Integer.valueOf(1); + Integer three = Integer.valueOf(3); + + Cache cache = cm.getCache("default"); + assertEquals(one, Integer.valueOf(service.conditionalUpdate(one).toString())); + assertNull(cache.get(one)); + + assertEquals(three, Integer.valueOf(service.conditionalUpdate(three).toString())); + assertEquals(three, Integer.valueOf(cache.get(three).get().toString())); + } + + public void testMultiCache(CacheableService<?> service) { + Object o1 = new Object(); + Object o2 = new Object(); + + Cache primary = cm.getCache("primary"); + Cache secondary = cm.getCache("secondary"); + + assertNull(primary.get(o1)); + assertNull(secondary.get(o1)); + Object r1 = service.multiCache(o1); + assertSame(r1, primary.get(o1).get()); + assertSame(r1, secondary.get(o1).get()); + + Object r2 = service.multiCache(o1); + Object r3 = service.multiCache(o1); + + assertSame(r1, r2); + assertSame(r1, r3); + + assertNull(primary.get(o2)); + assertNull(secondary.get(o2)); + Object r4 = service.multiCache(o2); + assertSame(r4, primary.get(o2).get()); + assertSame(r4, secondary.get(o2).get()); + } + + public void testMultiEvict(CacheableService<?> service) { + Object o1 = new Object(); + Object o2 = o1.toString() + "A"; + + + Object r1 = service.multiCache(o1); + Object r2 = service.multiCache(o1); + + Cache primary = cm.getCache("primary"); + Cache secondary = cm.getCache("secondary"); + + primary.put(o2, o2); + assertSame(r1, r2); + assertSame(r1, primary.get(o1).get()); + assertSame(r1, secondary.get(o1).get()); + + service.multiEvict(o1); + assertNull(primary.get(o1)); + assertNull(secondary.get(o1)); + assertNull(primary.get(o2)); + + Object r3 = service.multiCache(o1); + Object r4 = service.multiCache(o1); + assertNotSame(r1, r3); + assertSame(r3, r4); + + assertSame(r3, primary.get(o1).get()); + assertSame(r4, secondary.get(o1).get()); + } + + public void testMultiPut(CacheableService<?> service) { + Object o = Integer.valueOf(1); + + Cache primary = cm.getCache("primary"); + Cache secondary = cm.getCache("secondary"); + + assertNull(primary.get(o)); + assertNull(secondary.get(o)); + Object r1 = service.multiUpdate(o); + assertSame(r1, primary.get(o).get()); + assertSame(r1, secondary.get(o).get()); + + o = Integer.valueOf(2); + assertNull(primary.get(o)); + assertNull(secondary.get(o)); + Object r2 = service.multiUpdate(o); + assertSame(r2, primary.get(o).get()); + assertSame(r2, secondary.get(o).get()); + } + + public void testMultiCacheAndEvict(CacheableService<?> service) { + String methodName = "multiCacheAndEvict"; + + Cache primary = cm.getCache("primary"); + Cache secondary = cm.getCache("secondary"); + Object key = Integer.valueOf(1); + + secondary.put(key, key); + + assertNull(secondary.get(methodName)); + assertSame(key, secondary.get(key).get()); + + Object r1 = service.multiCacheAndEvict(key); + assertSame(r1, service.multiCacheAndEvict(key)); + + // assert the method name is used + assertSame(r1, primary.get(methodName).get()); + assertNull(secondary.get(methodName)); + assertNull(secondary.get(key)); + } + + public void testMultiConditionalCacheAndEvict(CacheableService<?> service) { + Cache primary = cm.getCache("primary"); + Cache secondary = cm.getCache("secondary"); + Object key = Integer.valueOf(1); + + secondary.put(key, key); + + assertNull(primary.get(key)); + assertSame(key, secondary.get(key).get()); + + Object r1 = service.multiConditionalCacheAndEvict(key); + Object r3 = service.multiConditionalCacheAndEvict(key); + + assertTrue(!r1.equals(r3)); + assertNull(primary.get(key)); + + Object key2 = Integer.valueOf(3); + Object r2 = service.multiConditionalCacheAndEvict(key2); + assertSame(r2, service.multiConditionalCacheAndEvict(key2)); + + // assert the method name is used + assertSame(r2, primary.get(key2).get()); + assertNull(secondary.get(key2)); + } + + @Test + public void testCacheable() throws Exception { + testCacheable(cs); + } + + @Test + public void testInvalidate() throws Exception { + testEvict(cs); + } + + @Test + public void testEarlyInvalidate() throws Exception { + testEvictEarly(cs); + } + + @Test + public void testEvictWithException() throws Exception { + testEvictException(cs); + } + + @Test + public void testEvictAll() throws Exception { + testEvictAll(cs); + } + + @Test + public void testInvalidateWithKey() throws Exception { + testEvictWKey(cs); + } + + @Test + public void testEarlyInvalidateWithKey() throws Exception { + testEvictWKeyEarly(cs); + } + + @Test + public void testConditionalExpression() throws Exception { + testConditionalExpression(cs); + } + + @Test + public void testKeyExpression() throws Exception { + testKeyExpression(cs); + } + + @Test + public void testClassCacheCacheable() throws Exception { + testCacheable(ccs); + } + + @Test + public void testClassCacheInvalidate() throws Exception { + testEvict(ccs); + } + + @Test + public void testClassEarlyInvalidate() throws Exception { + testEvictEarly(ccs); + } + + @Test + public void testClassEvictAll() throws Exception { + testEvictAll(ccs); + } + + @Test + public void testClassEvictWithException() throws Exception { + testEvictException(ccs); + } + + @Test + public void testClassCacheInvalidateWKey() throws Exception { + testEvictWKey(ccs); + } + + @Test + public void testClassEarlyInvalidateWithKey() throws Exception { + testEvictWKeyEarly(ccs); + } + + @Test + public void testNullValue() throws Exception { + testNullValue(cs); + } + + @Test + public void testClassNullValue() throws Exception { + Object key = new Object(); + assertNull(ccs.nullValue(key)); + int nr = ccs.nullInvocations().intValue(); + assertNull(ccs.nullValue(key)); + assertEquals(nr, ccs.nullInvocations().intValue()); + assertNull(ccs.nullValue(new Object())); + // the check method is also cached + assertEquals(nr, ccs.nullInvocations().intValue()); + assertEquals(nr + 1, AnnotatedClassCacheableService.nullInvocations.intValue()); + } + + @Test + public void testMethodName() throws Exception { + testMethodName(cs, "name"); + } + + @Test + public void testClassMethodName() throws Exception { + testMethodName(ccs, "namedefault"); + } + + @Test + public void testRootVars() throws Exception { + testRootVars(cs); + } + + @Test + public void testClassRootVars() throws Exception { + testRootVars(ccs); + } + + @Test + public void testNullArg() throws Exception { + testNullArg(cs); + } + + @Test + public void testClassNullArg() throws Exception { + testNullArg(ccs); + } + + @Test + public void testCheckedException() throws Exception { + testCheckedThrowable(cs); + } + + @Test + public void testClassCheckedException() throws Exception { + testCheckedThrowable(ccs); + } + + @Test + public void testUncheckedException() throws Exception { + testUncheckedThrowable(cs); + } + + @Test + public void testClassUncheckedException() throws Exception { + testUncheckedThrowable(ccs); + } + + @Test + public void testUpdate() { + testCacheUpdate(cs); + } + + @Test + public void testClassUpdate() { + testCacheUpdate(ccs); + } + + @Test + public void testConditionalUpdate() { + testConditionalCacheUpdate(cs); + } + + @Test + public void testClassConditionalUpdate() { + testConditionalCacheUpdate(ccs); + } + + @Test + public void testMultiCache() { + testMultiCache(cs); + } + + @Test + public void testClassMultiCache() { + testMultiCache(ccs); + } + + @Test + public void testMultiEvict() { + testMultiEvict(cs); + } + + @Test + public void testClassMultiEvict() { + testMultiEvict(ccs); + } + + @Test + public void testMultiPut() { + testMultiPut(cs); + } + + @Test + public void testClassMultiPut() { + testMultiPut(ccs); + } + + @Test + public void testMultiCacheAndEvict() { + testMultiCacheAndEvict(cs); + } + + @Test + public void testClassMultiCacheAndEvict() { + testMultiCacheAndEvict(ccs); + } + + @Test + public void testMultiConditionalCacheAndEvict() { + testMultiConditionalCacheAndEvict(cs); + } + + @Test + public void testClassMultiConditionalCacheAndEvict() { + testMultiConditionalCacheAndEvict(ccs); + } } \ No newline at end of file diff --git a/org.springframework.context/src/test/java/org/springframework/cache/config/AnnotatedClassCacheableService.java b/org.springframework.context/src/test/java/org/springframework/cache/config/AnnotatedClassCacheableService.java index 744963e6c09..573a5d8ffc1 100644 --- a/org.springframework.context/src/test/java/org/springframework/cache/config/AnnotatedClassCacheableService.java +++ b/org.springframework.context/src/test/java/org/springframework/cache/config/AnnotatedClassCacheableService.java @@ -1,138 +1,138 @@ -/* - * Copyright 2010-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cache.config; - -import java.util.concurrent.atomic.AtomicLong; - -import org.springframework.cache.annotation.CacheEvict; -import org.springframework.cache.annotation.CachePut; -import org.springframework.cache.annotation.Cacheable; -import org.springframework.cache.annotation.Caching; - -/** - * @author Costin Leau - */ -@Cacheable("default") -public class AnnotatedClassCacheableService implements CacheableService<Object> { - - private final AtomicLong counter = new AtomicLong(); - public static final AtomicLong nullInvocations = new AtomicLong(); - - public Object cache(Object arg1) { - return counter.getAndIncrement(); - } - - public Object conditional(int field) { - return null; - } - - @CacheEvict("default") - public void invalidate(Object arg1) { - } - - @CacheEvict("default") - public void evictWithException(Object arg1) { - throw new RuntimeException("exception thrown - evict should NOT occur"); - } - - @CacheEvict(value = "default", allEntries = true) - public void evictAll(Object arg1) { - } - - @CacheEvict(value = "default", beforeInvocation = true) - public void evictEarly(Object arg1) { - throw new RuntimeException("exception thrown - evict should still occur"); - } - - @CacheEvict(value = "default", key = "#p0") - public void evict(Object arg1, Object arg2) { - } - - @CacheEvict(value = "default", key = "#p0", beforeInvocation = true) - public void invalidateEarly(Object arg1, Object arg2) { - throw new RuntimeException("exception thrown - evict should still occur"); - } - - @Cacheable(value = "default", key = "#p0") - public Object key(Object arg1, Object arg2) { - return counter.getAndIncrement(); - } - - @Cacheable(value = "default", key = "#root.methodName + #root.caches[0].name") - public Object name(Object arg1) { - return counter.getAndIncrement(); - } - - @Cacheable(value = "default", key = "#root.methodName + #root.method.name + #root.targetClass + #root.target") - public Object rootVars(Object arg1) { - return counter.getAndIncrement(); - } - - @CachePut("default") - public Object update(Object arg1) { - return counter.getAndIncrement(); - } - - @CachePut(value = "default", condition = "#arg.equals(3)") - public Object conditionalUpdate(Object arg) { - return arg; - } - - public Object nullValue(Object arg1) { - nullInvocations.incrementAndGet(); - return null; - } - - public Number nullInvocations() { - return nullInvocations.get(); - } - - public Long throwChecked(Object arg1) throws Exception { - throw new UnsupportedOperationException(arg1.toString()); - } - - public Long throwUnchecked(Object arg1) { - throw new UnsupportedOperationException(); - } - - // multi annotations - - @Caching(cacheable = { @Cacheable("primary"), @Cacheable("secondary") }) - public Object multiCache(Object arg1) { - return counter.getAndIncrement(); - } - - @Caching(evict = { @CacheEvict("primary"), @CacheEvict(value = "secondary", key = "#p0"), @CacheEvict(value = "primary", key = "#p0 + 'A'") }) - public Object multiEvict(Object arg1) { - return counter.getAndIncrement(); - } - - @Caching(cacheable = { @Cacheable(value = "primary", key = "#root.methodName") }, evict = { @CacheEvict("secondary") }) - public Object multiCacheAndEvict(Object arg1) { - return counter.getAndIncrement(); - } - - @Caching(cacheable = { @Cacheable(value = "primary", condition = "#p0 == 3") }, evict = { @CacheEvict("secondary") }) - public Object multiConditionalCacheAndEvict(Object arg1) { - return counter.getAndIncrement(); - } - - @Caching(put = { @CachePut("primary"), @CachePut("secondary") }) - public Object multiUpdate(Object arg1) { - return arg1; - } +/* + * Copyright 2010-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cache.config; + +import java.util.concurrent.atomic.AtomicLong; + +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.CachePut; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.cache.annotation.Caching; + +/** + * @author Costin Leau + */ +@Cacheable("default") +public class AnnotatedClassCacheableService implements CacheableService<Object> { + + private final AtomicLong counter = new AtomicLong(); + public static final AtomicLong nullInvocations = new AtomicLong(); + + public Object cache(Object arg1) { + return counter.getAndIncrement(); + } + + public Object conditional(int field) { + return null; + } + + @CacheEvict("default") + public void invalidate(Object arg1) { + } + + @CacheEvict("default") + public void evictWithException(Object arg1) { + throw new RuntimeException("exception thrown - evict should NOT occur"); + } + + @CacheEvict(value = "default", allEntries = true) + public void evictAll(Object arg1) { + } + + @CacheEvict(value = "default", beforeInvocation = true) + public void evictEarly(Object arg1) { + throw new RuntimeException("exception thrown - evict should still occur"); + } + + @CacheEvict(value = "default", key = "#p0") + public void evict(Object arg1, Object arg2) { + } + + @CacheEvict(value = "default", key = "#p0", beforeInvocation = true) + public void invalidateEarly(Object arg1, Object arg2) { + throw new RuntimeException("exception thrown - evict should still occur"); + } + + @Cacheable(value = "default", key = "#p0") + public Object key(Object arg1, Object arg2) { + return counter.getAndIncrement(); + } + + @Cacheable(value = "default", key = "#root.methodName + #root.caches[0].name") + public Object name(Object arg1) { + return counter.getAndIncrement(); + } + + @Cacheable(value = "default", key = "#root.methodName + #root.method.name + #root.targetClass + #root.target") + public Object rootVars(Object arg1) { + return counter.getAndIncrement(); + } + + @CachePut("default") + public Object update(Object arg1) { + return counter.getAndIncrement(); + } + + @CachePut(value = "default", condition = "#arg.equals(3)") + public Object conditionalUpdate(Object arg) { + return arg; + } + + public Object nullValue(Object arg1) { + nullInvocations.incrementAndGet(); + return null; + } + + public Number nullInvocations() { + return nullInvocations.get(); + } + + public Long throwChecked(Object arg1) throws Exception { + throw new UnsupportedOperationException(arg1.toString()); + } + + public Long throwUnchecked(Object arg1) { + throw new UnsupportedOperationException(); + } + + // multi annotations + + @Caching(cacheable = { @Cacheable("primary"), @Cacheable("secondary") }) + public Object multiCache(Object arg1) { + return counter.getAndIncrement(); + } + + @Caching(evict = { @CacheEvict("primary"), @CacheEvict(value = "secondary", key = "#p0"), @CacheEvict(value = "primary", key = "#p0 + 'A'") }) + public Object multiEvict(Object arg1) { + return counter.getAndIncrement(); + } + + @Caching(cacheable = { @Cacheable(value = "primary", key = "#root.methodName") }, evict = { @CacheEvict("secondary") }) + public Object multiCacheAndEvict(Object arg1) { + return counter.getAndIncrement(); + } + + @Caching(cacheable = { @Cacheable(value = "primary", condition = "#p0 == 3") }, evict = { @CacheEvict("secondary") }) + public Object multiConditionalCacheAndEvict(Object arg1) { + return counter.getAndIncrement(); + } + + @Caching(put = { @CachePut("primary"), @CachePut("secondary") }) + public Object multiUpdate(Object arg1) { + return arg1; + } } \ No newline at end of file diff --git a/org.springframework.context/src/test/java/org/springframework/cache/config/AnnotationNamespaceDrivenTests.java b/org.springframework.context/src/test/java/org/springframework/cache/config/AnnotationNamespaceDrivenTests.java index 06ec9e8dbdf..44b931dfe6b 100644 --- a/org.springframework.context/src/test/java/org/springframework/cache/config/AnnotationNamespaceDrivenTests.java +++ b/org.springframework.context/src/test/java/org/springframework/cache/config/AnnotationNamespaceDrivenTests.java @@ -1,44 +1,44 @@ -/* - * Copyright 2010-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cache.config; - -import junit.framework.Assert; - -import org.junit.Test; -import org.springframework.cache.interceptor.CacheInterceptor; -import org.springframework.context.ApplicationContext; -import org.springframework.context.support.GenericXmlApplicationContext; - -/** - * @author Costin Leau - * @author Chris Beams - */ -public class AnnotationNamespaceDrivenTests extends AbstractAnnotationTests { - - @Override - protected ApplicationContext getApplicationContext() { - return new GenericXmlApplicationContext( - "/org/springframework/cache/config/annotationDrivenCacheNamespace.xml"); - } - - @Test - public void testKeyStrategy() throws Exception { - CacheInterceptor ci = ctx.getBean("org.springframework.cache.interceptor.CacheInterceptor#0", - CacheInterceptor.class); - Assert.assertSame(ctx.getBean("keyGenerator"), ci.getKeyGenerator()); - } -} +/* + * Copyright 2010-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cache.config; + +import junit.framework.Assert; + +import org.junit.Test; +import org.springframework.cache.interceptor.CacheInterceptor; +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.GenericXmlApplicationContext; + +/** + * @author Costin Leau + * @author Chris Beams + */ +public class AnnotationNamespaceDrivenTests extends AbstractAnnotationTests { + + @Override + protected ApplicationContext getApplicationContext() { + return new GenericXmlApplicationContext( + "/org/springframework/cache/config/annotationDrivenCacheNamespace.xml"); + } + + @Test + public void testKeyStrategy() throws Exception { + CacheInterceptor ci = ctx.getBean("org.springframework.cache.interceptor.CacheInterceptor#0", + CacheInterceptor.class); + Assert.assertSame(ctx.getBean("keyGenerator"), ci.getKeyGenerator()); + } +} diff --git a/org.springframework.context/src/test/java/org/springframework/cache/config/AnnotationTests.java b/org.springframework.context/src/test/java/org/springframework/cache/config/AnnotationTests.java index 8de9d7bb521..04c07fd2083 100644 --- a/org.springframework.context/src/test/java/org/springframework/cache/config/AnnotationTests.java +++ b/org.springframework.context/src/test/java/org/springframework/cache/config/AnnotationTests.java @@ -1,33 +1,33 @@ -/* - * Copyright 2010-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cache.config; - -import org.springframework.context.ApplicationContext; -import org.springframework.context.support.GenericXmlApplicationContext; - -/** - * @author Costin Leau - * @author Chris Beams - */ -public class AnnotationTests extends AbstractAnnotationTests { - - @Override - protected ApplicationContext getApplicationContext() { - return new GenericXmlApplicationContext( - "/org/springframework/cache/config/annotationDrivenCacheConfig.xml"); - } +/* + * Copyright 2010-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cache.config; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.GenericXmlApplicationContext; + +/** + * @author Costin Leau + * @author Chris Beams + */ +public class AnnotationTests extends AbstractAnnotationTests { + + @Override + protected ApplicationContext getApplicationContext() { + return new GenericXmlApplicationContext( + "/org/springframework/cache/config/annotationDrivenCacheConfig.xml"); + } } \ No newline at end of file diff --git a/org.springframework.context/src/test/java/org/springframework/cache/config/CacheAdviceNamespaceTests.java b/org.springframework.context/src/test/java/org/springframework/cache/config/CacheAdviceNamespaceTests.java index 09dcf34607b..e91a721b0c1 100644 --- a/org.springframework.context/src/test/java/org/springframework/cache/config/CacheAdviceNamespaceTests.java +++ b/org.springframework.context/src/test/java/org/springframework/cache/config/CacheAdviceNamespaceTests.java @@ -1,42 +1,42 @@ -/* - * Copyright 2010-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cache.config; - -import org.junit.Assert; -import org.junit.Test; -import org.springframework.cache.interceptor.CacheInterceptor; -import org.springframework.context.ApplicationContext; -import org.springframework.context.support.GenericXmlApplicationContext; - -/** - * @author Costin Leau - * @author Chris Beams - */ -public class CacheAdviceNamespaceTests extends AbstractAnnotationTests { - - @Override - protected ApplicationContext getApplicationContext() { - return new GenericXmlApplicationContext( - "/org/springframework/cache/config/cache-advice.xml"); - } - - @Test - public void testKeyStrategy() throws Exception { - CacheInterceptor bean = ctx.getBean("cacheAdviceClass", CacheInterceptor.class); - Assert.assertSame(ctx.getBean("keyGenerator"), bean.getKeyGenerator()); - } -} +/* + * Copyright 2010-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cache.config; + +import org.junit.Assert; +import org.junit.Test; +import org.springframework.cache.interceptor.CacheInterceptor; +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.GenericXmlApplicationContext; + +/** + * @author Costin Leau + * @author Chris Beams + */ +public class CacheAdviceNamespaceTests extends AbstractAnnotationTests { + + @Override + protected ApplicationContext getApplicationContext() { + return new GenericXmlApplicationContext( + "/org/springframework/cache/config/cache-advice.xml"); + } + + @Test + public void testKeyStrategy() throws Exception { + CacheInterceptor bean = ctx.getBean("cacheAdviceClass", CacheInterceptor.class); + Assert.assertSame(ctx.getBean("keyGenerator"), bean.getKeyGenerator()); + } +} diff --git a/org.springframework.context/src/test/java/org/springframework/cache/config/CacheableService.java b/org.springframework.context/src/test/java/org/springframework/cache/config/CacheableService.java index 1d03d9dbc50..870bdde66ba 100644 --- a/org.springframework.context/src/test/java/org/springframework/cache/config/CacheableService.java +++ b/org.springframework.context/src/test/java/org/springframework/cache/config/CacheableService.java @@ -1,70 +1,70 @@ -/* - * Copyright 2010-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cache.config; - -/** - * Basic service interface. - * - * @author Costin Leau - */ -public interface CacheableService<T> { - - T cache(Object arg1); - - void invalidate(Object arg1); - - void evictEarly(Object arg1); - - void evictAll(Object arg1); - - void evictWithException(Object arg1); - - void evict(Object arg1, Object arg2); - - void invalidateEarly(Object arg1, Object arg2); - - T conditional(int field); - - T key(Object arg1, Object arg2); - - T name(Object arg1); - - T nullValue(Object arg1); - - T update(Object arg1); - - T conditionalUpdate(Object arg2); - - Number nullInvocations(); - - T rootVars(Object arg1); - - T throwChecked(Object arg1) throws Exception; - - T throwUnchecked(Object arg1); - - // multi annotations - T multiCache(Object arg1); - - T multiEvict(Object arg1); - - T multiCacheAndEvict(Object arg1); - - T multiConditionalCacheAndEvict(Object arg1); - - T multiUpdate(Object arg1); +/* + * Copyright 2010-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cache.config; + +/** + * Basic service interface. + * + * @author Costin Leau + */ +public interface CacheableService<T> { + + T cache(Object arg1); + + void invalidate(Object arg1); + + void evictEarly(Object arg1); + + void evictAll(Object arg1); + + void evictWithException(Object arg1); + + void evict(Object arg1, Object arg2); + + void invalidateEarly(Object arg1, Object arg2); + + T conditional(int field); + + T key(Object arg1, Object arg2); + + T name(Object arg1); + + T nullValue(Object arg1); + + T update(Object arg1); + + T conditionalUpdate(Object arg2); + + Number nullInvocations(); + + T rootVars(Object arg1); + + T throwChecked(Object arg1) throws Exception; + + T throwUnchecked(Object arg1); + + // multi annotations + T multiCache(Object arg1); + + T multiEvict(Object arg1); + + T multiCacheAndEvict(Object arg1); + + T multiConditionalCacheAndEvict(Object arg1); + + T multiUpdate(Object arg1); } \ No newline at end of file diff --git a/org.springframework.context/src/test/java/org/springframework/cache/config/DefaultCacheableService.java b/org.springframework.context/src/test/java/org/springframework/cache/config/DefaultCacheableService.java index 0f7493c554b..fc754b6c3d1 100644 --- a/org.springframework.context/src/test/java/org/springframework/cache/config/DefaultCacheableService.java +++ b/org.springframework.context/src/test/java/org/springframework/cache/config/DefaultCacheableService.java @@ -1,144 +1,144 @@ -/* - * Copyright 2010-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cache.config; - -import java.util.concurrent.atomic.AtomicLong; - -import org.springframework.cache.annotation.CacheEvict; -import org.springframework.cache.annotation.CachePut; -import org.springframework.cache.annotation.Cacheable; -import org.springframework.cache.annotation.Caching; - -/** - * Simple cacheable service - * - * @author Costin Leau - */ -public class DefaultCacheableService implements CacheableService<Long> { - - private final AtomicLong counter = new AtomicLong(); - private final AtomicLong nullInvocations = new AtomicLong(); - - @Cacheable("default") - public Long cache(Object arg1) { - return counter.getAndIncrement(); - } - - @CacheEvict("default") - public void invalidate(Object arg1) { - } - - @CacheEvict("default") - public void evictWithException(Object arg1) { - throw new RuntimeException("exception thrown - evict should NOT occur"); - } - - @CacheEvict(value = "default", allEntries = true) - public void evictAll(Object arg1) { - } - - @CacheEvict(value = "default", beforeInvocation = true) - public void evictEarly(Object arg1) { - throw new RuntimeException("exception thrown - evict should still occur"); - } - - @CacheEvict(value = "default", key = "#p0") - public void evict(Object arg1, Object arg2) { - } - - @CacheEvict(value = "default", key = "#p0", beforeInvocation = true) - public void invalidateEarly(Object arg1, Object arg2) { - throw new RuntimeException("exception thrown - evict should still occur"); - } - - @Cacheable(value = "default", condition = "#classField == 3") - public Long conditional(int classField) { - return counter.getAndIncrement(); - } - - @Cacheable(value = "default", key = "#p0") - public Long key(Object arg1, Object arg2) { - return counter.getAndIncrement(); - } - - @Cacheable(value = "default", key = "#root.methodName") - public Long name(Object arg1) { - return counter.getAndIncrement(); - } - - @Cacheable(value = "default", key = "#root.methodName + #root.method.name + #root.targetClass + #root.target") - public Long rootVars(Object arg1) { - return counter.getAndIncrement(); - } - - @CachePut("default") - public Long update(Object arg1) { - return counter.getAndIncrement(); - } - - @CachePut(value = "default", condition = "#arg.equals(3)") - public Long conditionalUpdate(Object arg) { - return Long.valueOf(arg.toString()); - } - - @Cacheable("default") - public Long nullValue(Object arg1) { - nullInvocations.incrementAndGet(); - return null; - } - - public Number nullInvocations() { - return nullInvocations.get(); - } - - @Cacheable("default") - public Long throwChecked(Object arg1) throws Exception { - throw new Exception(arg1.toString()); - } - - @Cacheable("default") - public Long throwUnchecked(Object arg1) { - throw new UnsupportedOperationException(arg1.toString()); - } - - // multi annotations - - @Caching(cacheable = { @Cacheable("primary"), @Cacheable("secondary") }) - public Long multiCache(Object arg1) { - return counter.getAndIncrement(); - } - - @Caching(evict = { @CacheEvict("primary"), @CacheEvict(value = "secondary", key = "#p0"), @CacheEvict(value = "primary", key = "#p0 + 'A'") }) - public Long multiEvict(Object arg1) { - return counter.getAndIncrement(); - } - - @Caching(cacheable = { @Cacheable(value = "primary", key = "#root.methodName") }, evict = { @CacheEvict("secondary") }) - public Long multiCacheAndEvict(Object arg1) { - return counter.getAndIncrement(); - } - - @Caching(cacheable = { @Cacheable(value = "primary", condition = "#p0 == 3") }, evict = { @CacheEvict("secondary") }) - public Long multiConditionalCacheAndEvict(Object arg1) { - return counter.getAndIncrement(); - } - - @Caching(put = { @CachePut("primary"), @CachePut("secondary") }) - public Long multiUpdate(Object arg1) { - return Long.valueOf(arg1.toString()); - } +/* + * Copyright 2010-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cache.config; + +import java.util.concurrent.atomic.AtomicLong; + +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.CachePut; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.cache.annotation.Caching; + +/** + * Simple cacheable service + * + * @author Costin Leau + */ +public class DefaultCacheableService implements CacheableService<Long> { + + private final AtomicLong counter = new AtomicLong(); + private final AtomicLong nullInvocations = new AtomicLong(); + + @Cacheable("default") + public Long cache(Object arg1) { + return counter.getAndIncrement(); + } + + @CacheEvict("default") + public void invalidate(Object arg1) { + } + + @CacheEvict("default") + public void evictWithException(Object arg1) { + throw new RuntimeException("exception thrown - evict should NOT occur"); + } + + @CacheEvict(value = "default", allEntries = true) + public void evictAll(Object arg1) { + } + + @CacheEvict(value = "default", beforeInvocation = true) + public void evictEarly(Object arg1) { + throw new RuntimeException("exception thrown - evict should still occur"); + } + + @CacheEvict(value = "default", key = "#p0") + public void evict(Object arg1, Object arg2) { + } + + @CacheEvict(value = "default", key = "#p0", beforeInvocation = true) + public void invalidateEarly(Object arg1, Object arg2) { + throw new RuntimeException("exception thrown - evict should still occur"); + } + + @Cacheable(value = "default", condition = "#classField == 3") + public Long conditional(int classField) { + return counter.getAndIncrement(); + } + + @Cacheable(value = "default", key = "#p0") + public Long key(Object arg1, Object arg2) { + return counter.getAndIncrement(); + } + + @Cacheable(value = "default", key = "#root.methodName") + public Long name(Object arg1) { + return counter.getAndIncrement(); + } + + @Cacheable(value = "default", key = "#root.methodName + #root.method.name + #root.targetClass + #root.target") + public Long rootVars(Object arg1) { + return counter.getAndIncrement(); + } + + @CachePut("default") + public Long update(Object arg1) { + return counter.getAndIncrement(); + } + + @CachePut(value = "default", condition = "#arg.equals(3)") + public Long conditionalUpdate(Object arg) { + return Long.valueOf(arg.toString()); + } + + @Cacheable("default") + public Long nullValue(Object arg1) { + nullInvocations.incrementAndGet(); + return null; + } + + public Number nullInvocations() { + return nullInvocations.get(); + } + + @Cacheable("default") + public Long throwChecked(Object arg1) throws Exception { + throw new Exception(arg1.toString()); + } + + @Cacheable("default") + public Long throwUnchecked(Object arg1) { + throw new UnsupportedOperationException(arg1.toString()); + } + + // multi annotations + + @Caching(cacheable = { @Cacheable("primary"), @Cacheable("secondary") }) + public Long multiCache(Object arg1) { + return counter.getAndIncrement(); + } + + @Caching(evict = { @CacheEvict("primary"), @CacheEvict(value = "secondary", key = "#p0"), @CacheEvict(value = "primary", key = "#p0 + 'A'") }) + public Long multiEvict(Object arg1) { + return counter.getAndIncrement(); + } + + @Caching(cacheable = { @Cacheable(value = "primary", key = "#root.methodName") }, evict = { @CacheEvict("secondary") }) + public Long multiCacheAndEvict(Object arg1) { + return counter.getAndIncrement(); + } + + @Caching(cacheable = { @Cacheable(value = "primary", condition = "#p0 == 3") }, evict = { @CacheEvict("secondary") }) + public Long multiConditionalCacheAndEvict(Object arg1) { + return counter.getAndIncrement(); + } + + @Caching(put = { @CachePut("primary"), @CachePut("secondary") }) + public Long multiUpdate(Object arg1) { + return Long.valueOf(arg1.toString()); + } } \ No newline at end of file diff --git a/org.springframework.context/src/test/java/org/springframework/cache/config/SomeKeyGenerator.java b/org.springframework.context/src/test/java/org/springframework/cache/config/SomeKeyGenerator.java index fb38a7ea6d9..7c1571f39be 100644 --- a/org.springframework.context/src/test/java/org/springframework/cache/config/SomeKeyGenerator.java +++ b/org.springframework.context/src/test/java/org/springframework/cache/config/SomeKeyGenerator.java @@ -1,23 +1,23 @@ -/* - * Copyright 2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cache.config; - -import org.springframework.cache.interceptor.DefaultKeyGenerator; - -public class SomeKeyGenerator extends DefaultKeyGenerator { - -} +/* + * Copyright 2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cache.config; + +import org.springframework.cache.interceptor.DefaultKeyGenerator; + +public class SomeKeyGenerator extends DefaultKeyGenerator { + +} diff --git a/org.springframework.context/src/test/java/org/springframework/cache/ehcache/EhCacheCacheTests.java b/org.springframework.context/src/test/java/org/springframework/cache/ehcache/EhCacheCacheTests.java index e007e1f5c61..3b188a585a1 100644 --- a/org.springframework.context/src/test/java/org/springframework/cache/ehcache/EhCacheCacheTests.java +++ b/org.springframework.context/src/test/java/org/springframework/cache/ehcache/EhCacheCacheTests.java @@ -1,62 +1,62 @@ -/* - * Copyright 2010-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cache.ehcache; - -import static org.junit.Assert.*; -import net.sf.ehcache.Ehcache; -import net.sf.ehcache.Element; - -import org.junit.Test; -import org.springframework.cache.Cache; -import org.springframework.cache.vendor.AbstractNativeCacheTests; - -/** - * Integration test for EhCache cache. - * - * @author Costin Leau - */ -public class EhCacheCacheTests extends AbstractNativeCacheTests<Ehcache> { - - @Override - protected Ehcache createNativeCache() throws Exception { - EhCacheFactoryBean fb = new EhCacheFactoryBean(); - fb.setBeanName(CACHE_NAME); - fb.setCacheName(CACHE_NAME); - fb.afterPropertiesSet(); - return fb.getObject(); - } - - @Override - protected Cache createCache(Ehcache nativeCache) { - return new EhCacheCache(nativeCache); - } - - @Test - public void testExpiredElements() throws Exception { - String key = "brancusi"; - String value = "constantin"; - Element brancusi = new Element(key, value); - // ttl = 10s - brancusi.setTimeToLive(3); - nativeCache.put(brancusi); - - assertEquals(value, cache.get(key).get()); - // wait for the entry to expire - Thread.sleep(5 * 1000); - assertNull(cache.get(key)); - } +/* + * Copyright 2010-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cache.ehcache; + +import static org.junit.Assert.*; +import net.sf.ehcache.Ehcache; +import net.sf.ehcache.Element; + +import org.junit.Test; +import org.springframework.cache.Cache; +import org.springframework.cache.vendor.AbstractNativeCacheTests; + +/** + * Integration test for EhCache cache. + * + * @author Costin Leau + */ +public class EhCacheCacheTests extends AbstractNativeCacheTests<Ehcache> { + + @Override + protected Ehcache createNativeCache() throws Exception { + EhCacheFactoryBean fb = new EhCacheFactoryBean(); + fb.setBeanName(CACHE_NAME); + fb.setCacheName(CACHE_NAME); + fb.afterPropertiesSet(); + return fb.getObject(); + } + + @Override + protected Cache createCache(Ehcache nativeCache) { + return new EhCacheCache(nativeCache); + } + + @Test + public void testExpiredElements() throws Exception { + String key = "brancusi"; + String value = "constantin"; + Element brancusi = new Element(key, value); + // ttl = 10s + brancusi.setTimeToLive(3); + nativeCache.put(brancusi); + + assertEquals(value, cache.get(key).get()); + // wait for the entry to expire + Thread.sleep(5 * 1000); + assertNull(cache.get(key)); + } } \ No newline at end of file diff --git a/org.springframework.context/src/test/java/org/springframework/cache/vendor/AbstractNativeCacheTests.java b/org.springframework.context/src/test/java/org/springframework/cache/vendor/AbstractNativeCacheTests.java index e4bf138c198..7afc1d1c27c 100644 --- a/org.springframework.context/src/test/java/org/springframework/cache/vendor/AbstractNativeCacheTests.java +++ b/org.springframework.context/src/test/java/org/springframework/cache/vendor/AbstractNativeCacheTests.java @@ -1,88 +1,88 @@ -/* - * Copyright 2010-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cache.vendor; - -import static org.junit.Assert.*; - -import org.junit.Before; -import org.junit.Test; -import org.springframework.cache.Cache; - -/** - * Test for native cache implementations. - * - * @author Costin Leau - */ -public abstract class AbstractNativeCacheTests<T> { - - protected T nativeCache; - protected Cache cache; - protected final static String CACHE_NAME = "testCache"; - - @Before - public void setUp() throws Exception { - nativeCache = createNativeCache(); - cache = createCache(nativeCache); - cache.clear(); - } - - - protected abstract T createNativeCache() throws Exception; - - protected abstract Cache createCache(T nativeCache); - - - @Test - public void testCacheName() throws Exception { - assertEquals(CACHE_NAME, cache.getName()); - } - - @Test - public void testNativeCache() throws Exception { - assertSame(nativeCache, cache.getNativeCache()); - } - - @Test - public void testCachePut() throws Exception { - Object key = "enescu"; - Object value = "george"; - - assertNull(cache.get(key)); - cache.put(key, value); - assertEquals(value, cache.get(key).get()); - } - - @Test - public void testCacheRemove() throws Exception { - Object key = "enescu"; - Object value = "george"; - - assertNull(cache.get(key)); - cache.put(key, value); - } - - @Test - public void testCacheClear() throws Exception { - assertNull(cache.get("enescu")); - cache.put("enescu", "george"); - assertNull(cache.get("vlaicu")); - cache.put("vlaicu", "aurel"); - cache.clear(); - assertNull(cache.get("vlaicu")); - assertNull(cache.get("enescu")); - } +/* + * Copyright 2010-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cache.vendor; + +import static org.junit.Assert.*; + +import org.junit.Before; +import org.junit.Test; +import org.springframework.cache.Cache; + +/** + * Test for native cache implementations. + * + * @author Costin Leau + */ +public abstract class AbstractNativeCacheTests<T> { + + protected T nativeCache; + protected Cache cache; + protected final static String CACHE_NAME = "testCache"; + + @Before + public void setUp() throws Exception { + nativeCache = createNativeCache(); + cache = createCache(nativeCache); + cache.clear(); + } + + + protected abstract T createNativeCache() throws Exception; + + protected abstract Cache createCache(T nativeCache); + + + @Test + public void testCacheName() throws Exception { + assertEquals(CACHE_NAME, cache.getName()); + } + + @Test + public void testNativeCache() throws Exception { + assertSame(nativeCache, cache.getNativeCache()); + } + + @Test + public void testCachePut() throws Exception { + Object key = "enescu"; + Object value = "george"; + + assertNull(cache.get(key)); + cache.put(key, value); + assertEquals(value, cache.get(key).get()); + } + + @Test + public void testCacheRemove() throws Exception { + Object key = "enescu"; + Object value = "george"; + + assertNull(cache.get(key)); + cache.put(key, value); + } + + @Test + public void testCacheClear() throws Exception { + assertNull(cache.get("enescu")); + cache.put("enescu", "george"); + assertNull(cache.get("vlaicu")); + cache.put("vlaicu", "aurel"); + cache.clear(); + assertNull(cache.get("vlaicu")); + assertNull(cache.get("enescu")); + } } \ No newline at end of file diff --git a/org.springframework.context/src/test/java/org/springframework/context/annotation/BeanAge.java b/org.springframework.context/src/test/java/org/springframework/context/annotation/BeanAge.java index 514404b5c83..7d53b3a2cd5 100644 --- a/org.springframework.context/src/test/java/org/springframework/context/annotation/BeanAge.java +++ b/org.springframework.context/src/test/java/org/springframework/context/annotation/BeanAge.java @@ -1,16 +1,16 @@ -package org.springframework.context.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.beans.factory.annotation.Qualifier; - - -@Target({ElementType.METHOD, ElementType.PARAMETER}) -@Retention(RetentionPolicy.RUNTIME) -@Qualifier -public @interface BeanAge { - int value(); -} +package org.springframework.context.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.beans.factory.annotation.Qualifier; + + +@Target({ElementType.METHOD, ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +@Qualifier +public @interface BeanAge { + int value(); +} diff --git a/org.springframework.context/src/test/java/org/springframework/context/annotation/ClassPathFactoryBeanDefinitionScannerTests.java b/org.springframework.context/src/test/java/org/springframework/context/annotation/ClassPathFactoryBeanDefinitionScannerTests.java index a19fa4ed84f..36d950e1102 100644 --- a/org.springframework.context/src/test/java/org/springframework/context/annotation/ClassPathFactoryBeanDefinitionScannerTests.java +++ b/org.springframework.context/src/test/java/org/springframework/context/annotation/ClassPathFactoryBeanDefinitionScannerTests.java @@ -1,95 +1,95 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.context.annotation; - -import junit.framework.TestCase; - -import org.springframework.aop.scope.ScopedObject; -import org.springframework.aop.support.AopUtils; -import org.springframework.beans.TestBean; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.beans.factory.config.SimpleMapScope; -import org.springframework.beans.factory.support.RootBeanDefinition; -import org.springframework.context.annotation4.DependencyBean; -import org.springframework.context.annotation4.FactoryMethodComponent; -import org.springframework.context.support.GenericApplicationContext; -import org.springframework.util.ClassUtils; - -/** - * @author Mark Pollack - * @author Juergen Hoeller - */ -public class ClassPathFactoryBeanDefinitionScannerTests extends TestCase { - - private static final String BASE_PACKAGE = FactoryMethodComponent.class.getPackage().getName(); - - - public void testSingletonScopedFactoryMethod() { - GenericApplicationContext context = new GenericApplicationContext(); - ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context); - - context.getBeanFactory().registerScope("request", new SimpleMapScope()); - - scanner.scan(BASE_PACKAGE); - context.registerBeanDefinition("clientBean", new RootBeanDefinition(QualifiedClientBean.class)); - context.refresh(); - - FactoryMethodComponent fmc = context.getBean("factoryMethodComponent", FactoryMethodComponent.class); - assertFalse(fmc.getClass().getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)); - - TestBean tb = (TestBean)context.getBean("publicInstance"); //2 - assertEquals("publicInstance", tb.getName()); - TestBean tb2 = (TestBean)context.getBean("publicInstance"); //2 - assertEquals("publicInstance", tb2.getName()); - assertSame(tb2, tb); - - tb = (TestBean)context.getBean("protectedInstance"); //3 - assertEquals("protectedInstance", tb.getName()); - assertSame(tb, context.getBean("protectedInstance")); - assertEquals("0", tb.getCountry()); - tb2 = context.getBean("protectedInstance", TestBean.class); //3 - assertEquals("protectedInstance", tb2.getName()); - assertSame(tb2, tb); - - tb = context.getBean("privateInstance", TestBean.class); //4 - assertEquals("privateInstance", tb.getName()); - assertEquals(1, tb.getAge()); - tb2 = context.getBean("privateInstance", TestBean.class); //4 - assertEquals(2, tb2.getAge()); - assertNotSame(tb2, tb); - - Object bean = context.getBean("requestScopedInstance"); //5 - assertTrue(AopUtils.isCglibProxy(bean)); - assertTrue(bean instanceof ScopedObject); - - QualifiedClientBean clientBean = context.getBean("clientBean", QualifiedClientBean.class); - assertSame(clientBean.testBean, context.getBean("publicInstance")); - assertSame(clientBean.dependencyBean, context.getBean("dependencyBean")); - } - - - public static class QualifiedClientBean { - - @Autowired @Qualifier("public") - public TestBean testBean; - - @Autowired - public DependencyBean dependencyBean; - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.context.annotation; + +import junit.framework.TestCase; + +import org.springframework.aop.scope.ScopedObject; +import org.springframework.aop.support.AopUtils; +import org.springframework.beans.TestBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.config.SimpleMapScope; +import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.context.annotation4.DependencyBean; +import org.springframework.context.annotation4.FactoryMethodComponent; +import org.springframework.context.support.GenericApplicationContext; +import org.springframework.util.ClassUtils; + +/** + * @author Mark Pollack + * @author Juergen Hoeller + */ +public class ClassPathFactoryBeanDefinitionScannerTests extends TestCase { + + private static final String BASE_PACKAGE = FactoryMethodComponent.class.getPackage().getName(); + + + public void testSingletonScopedFactoryMethod() { + GenericApplicationContext context = new GenericApplicationContext(); + ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context); + + context.getBeanFactory().registerScope("request", new SimpleMapScope()); + + scanner.scan(BASE_PACKAGE); + context.registerBeanDefinition("clientBean", new RootBeanDefinition(QualifiedClientBean.class)); + context.refresh(); + + FactoryMethodComponent fmc = context.getBean("factoryMethodComponent", FactoryMethodComponent.class); + assertFalse(fmc.getClass().getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)); + + TestBean tb = (TestBean)context.getBean("publicInstance"); //2 + assertEquals("publicInstance", tb.getName()); + TestBean tb2 = (TestBean)context.getBean("publicInstance"); //2 + assertEquals("publicInstance", tb2.getName()); + assertSame(tb2, tb); + + tb = (TestBean)context.getBean("protectedInstance"); //3 + assertEquals("protectedInstance", tb.getName()); + assertSame(tb, context.getBean("protectedInstance")); + assertEquals("0", tb.getCountry()); + tb2 = context.getBean("protectedInstance", TestBean.class); //3 + assertEquals("protectedInstance", tb2.getName()); + assertSame(tb2, tb); + + tb = context.getBean("privateInstance", TestBean.class); //4 + assertEquals("privateInstance", tb.getName()); + assertEquals(1, tb.getAge()); + tb2 = context.getBean("privateInstance", TestBean.class); //4 + assertEquals(2, tb2.getAge()); + assertNotSame(tb2, tb); + + Object bean = context.getBean("requestScopedInstance"); //5 + assertTrue(AopUtils.isCglibProxy(bean)); + assertTrue(bean instanceof ScopedObject); + + QualifiedClientBean clientBean = context.getBean("clientBean", QualifiedClientBean.class); + assertSame(clientBean.testBean, context.getBean("publicInstance")); + assertSame(clientBean.dependencyBean, context.getBean("dependencyBean")); + } + + + public static class QualifiedClientBean { + + @Autowired @Qualifier("public") + public TestBean testBean; + + @Autowired + public DependencyBean dependencyBean; + } + +} diff --git a/org.springframework.context/src/test/java/org/springframework/context/annotation/FooServiceDependentConverter.java b/org.springframework.context/src/test/java/org/springframework/context/annotation/FooServiceDependentConverter.java index 16e2773f9f5..4546a22de08 100644 --- a/org.springframework.context/src/test/java/org/springframework/context/annotation/FooServiceDependentConverter.java +++ b/org.springframework.context/src/test/java/org/springframework/context/annotation/FooServiceDependentConverter.java @@ -1,38 +1,38 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.context.annotation; - -import example.scannable.FooService; - -import org.springframework.core.convert.converter.Converter; - -/** - * @author Juergen Hoeller - */ -public class FooServiceDependentConverter implements Converter<String, org.springframework.beans.TestBean> { - - private FooService fooService; - - public void setFooService(FooService fooService) { - this.fooService = fooService; - } - - public org.springframework.beans.TestBean convert(String source) { - return new org.springframework.beans.TestBean(source); - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.context.annotation; + +import example.scannable.FooService; + +import org.springframework.core.convert.converter.Converter; + +/** + * @author Juergen Hoeller + */ +public class FooServiceDependentConverter implements Converter<String, org.springframework.beans.TestBean> { + + private FooService fooService; + + public void setFooService(FooService fooService) { + this.fooService = fooService; + } + + public org.springframework.beans.TestBean convert(String source) { + return new org.springframework.beans.TestBean(source); + } + +} diff --git a/org.springframework.context/src/test/java/org/springframework/context/annotation/jsr330/SpringAtInjectTck.java b/org.springframework.context/src/test/java/org/springframework/context/annotation/jsr330/SpringAtInjectTck.java index 860430c3478..80caecf6c56 100644 --- a/org.springframework.context/src/test/java/org/springframework/context/annotation/jsr330/SpringAtInjectTck.java +++ b/org.springframework.context/src/test/java/org/springframework/context/annotation/jsr330/SpringAtInjectTck.java @@ -1,63 +1,63 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.context.annotation.jsr330; - -import junit.framework.Test; -import org.atinject.tck.Tck; -import org.atinject.tck.auto.Car; -import org.atinject.tck.auto.Convertible; -import org.atinject.tck.auto.Drivers; -import org.atinject.tck.auto.DriversSeat; -import org.atinject.tck.auto.FuelTank; -import org.atinject.tck.auto.Seat; -import org.atinject.tck.auto.Tire; -import org.atinject.tck.auto.V8Engine; -import org.atinject.tck.auto.accessories.Cupholder; -import org.atinject.tck.auto.accessories.SpareTire; - -import org.springframework.context.annotation.AnnotatedBeanDefinitionReader; -import org.springframework.context.annotation.Jsr330ScopeMetadataResolver; -import org.springframework.context.annotation.Primary; -import org.springframework.context.support.GenericApplicationContext; - -/** - * @author Juergen Hoeller - * @since 3.0 - */ -public class SpringAtInjectTck { - - public static Test suite() { - GenericApplicationContext ac = new GenericApplicationContext(); - AnnotatedBeanDefinitionReader bdr = new AnnotatedBeanDefinitionReader(ac); - bdr.setScopeMetadataResolver(new Jsr330ScopeMetadataResolver()); - - bdr.registerBean(Convertible.class); - bdr.registerBean(DriversSeat.class, Drivers.class); - bdr.registerBean(Seat.class, Primary.class); - bdr.registerBean(V8Engine.class); - bdr.registerBean(SpareTire.class, "spare"); - bdr.registerBean(Cupholder.class); - bdr.registerBean(Tire.class, Primary.class); - bdr.registerBean(FuelTank.class); - - ac.refresh(); - Car car = ac.getBean(Car.class); - - return Tck.testsFor(car, false, true); - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.context.annotation.jsr330; + +import junit.framework.Test; +import org.atinject.tck.Tck; +import org.atinject.tck.auto.Car; +import org.atinject.tck.auto.Convertible; +import org.atinject.tck.auto.Drivers; +import org.atinject.tck.auto.DriversSeat; +import org.atinject.tck.auto.FuelTank; +import org.atinject.tck.auto.Seat; +import org.atinject.tck.auto.Tire; +import org.atinject.tck.auto.V8Engine; +import org.atinject.tck.auto.accessories.Cupholder; +import org.atinject.tck.auto.accessories.SpareTire; + +import org.springframework.context.annotation.AnnotatedBeanDefinitionReader; +import org.springframework.context.annotation.Jsr330ScopeMetadataResolver; +import org.springframework.context.annotation.Primary; +import org.springframework.context.support.GenericApplicationContext; + +/** + * @author Juergen Hoeller + * @since 3.0 + */ +public class SpringAtInjectTck { + + public static Test suite() { + GenericApplicationContext ac = new GenericApplicationContext(); + AnnotatedBeanDefinitionReader bdr = new AnnotatedBeanDefinitionReader(ac); + bdr.setScopeMetadataResolver(new Jsr330ScopeMetadataResolver()); + + bdr.registerBean(Convertible.class); + bdr.registerBean(DriversSeat.class, Drivers.class); + bdr.registerBean(Seat.class, Primary.class); + bdr.registerBean(V8Engine.class); + bdr.registerBean(SpareTire.class, "spare"); + bdr.registerBean(Cupholder.class); + bdr.registerBean(Tire.class, Primary.class); + bdr.registerBean(FuelTank.class); + + ac.refresh(); + Car car = ac.getBean(Car.class); + + return Tck.testsFor(car, false, true); + } + +} diff --git a/org.springframework.context/src/test/java/org/springframework/context/annotation4/DependencyBean.java b/org.springframework.context/src/test/java/org/springframework/context/annotation4/DependencyBean.java index 33f3634dc4b..c6e00ee243d 100644 --- a/org.springframework.context/src/test/java/org/springframework/context/annotation4/DependencyBean.java +++ b/org.springframework.context/src/test/java/org/springframework/context/annotation4/DependencyBean.java @@ -1,27 +1,27 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.context.annotation4; - -import org.springframework.stereotype.Component; - -/** - * @author Juergen Hoeller - */ -@Component -public class DependencyBean { - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.context.annotation4; + +import org.springframework.stereotype.Component; + +/** + * @author Juergen Hoeller + */ +@Component +public class DependencyBean { + +} diff --git a/org.springframework.context/src/test/java/org/springframework/context/annotation4/FactoryMethodComponent.java b/org.springframework.context/src/test/java/org/springframework/context/annotation4/FactoryMethodComponent.java index fbf5b7e6d69..125c77c6363 100644 --- a/org.springframework.context/src/test/java/org/springframework/context/annotation4/FactoryMethodComponent.java +++ b/org.springframework.context/src/test/java/org/springframework/context/annotation4/FactoryMethodComponent.java @@ -1,77 +1,77 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.context.annotation4; - -import org.springframework.beans.TestBean; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.BeanAge; -import org.springframework.context.annotation.Scope; -import org.springframework.context.annotation.ScopedProxyMode; -import org.springframework.stereotype.Component; - -/** - * Class used to test the functionality of factory method bean definitions - * declared inside a Spring component class. - * - * @author Mark Pollack - * @author Juergen Hoeller - */ -@Component -public final class FactoryMethodComponent { - - private int i; - - public static TestBean nullInstance() { - return null; - } - - @Bean @Qualifier("public") - public TestBean publicInstance() { - return new TestBean("publicInstance"); - } - - // to be ignored - public TestBean publicInstance(boolean doIt) { - return new TestBean("publicInstance"); - } - - @Bean @BeanAge(1) - protected TestBean protectedInstance(@Qualifier("public") TestBean spouse, @Value("#{privateInstance.age}") String country) { - TestBean tb = new TestBean("protectedInstance", 1); - tb.setSpouse(tb); - tb.setCountry(country); - return tb; - } - - @Bean @Scope("prototype") - private TestBean privateInstance() { - return new TestBean("privateInstance", i++); - } - - @Bean @Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS) - public TestBean requestScopedInstance() { - return new TestBean("requestScopedInstance", 3); - } - - @Bean - public DependencyBean secondInstance() { - return new DependencyBean(); - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.context.annotation4; + +import org.springframework.beans.TestBean; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.BeanAge; +import org.springframework.context.annotation.Scope; +import org.springframework.context.annotation.ScopedProxyMode; +import org.springframework.stereotype.Component; + +/** + * Class used to test the functionality of factory method bean definitions + * declared inside a Spring component class. + * + * @author Mark Pollack + * @author Juergen Hoeller + */ +@Component +public final class FactoryMethodComponent { + + private int i; + + public static TestBean nullInstance() { + return null; + } + + @Bean @Qualifier("public") + public TestBean publicInstance() { + return new TestBean("publicInstance"); + } + + // to be ignored + public TestBean publicInstance(boolean doIt) { + return new TestBean("publicInstance"); + } + + @Bean @BeanAge(1) + protected TestBean protectedInstance(@Qualifier("public") TestBean spouse, @Value("#{privateInstance.age}") String country) { + TestBean tb = new TestBean("protectedInstance", 1); + tb.setSpouse(tb); + tb.setCountry(country); + return tb; + } + + @Bean @Scope("prototype") + private TestBean privateInstance() { + return new TestBean("privateInstance", i++); + } + + @Bean @Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS) + public TestBean requestScopedInstance() { + return new TestBean("requestScopedInstance", 3); + } + + @Bean + public DependencyBean secondInstance() { + return new DependencyBean(); + } + +} diff --git a/org.springframework.context/src/test/java/org/springframework/context/annotation4/SimpleBean.java b/org.springframework.context/src/test/java/org/springframework/context/annotation4/SimpleBean.java index e6920157d4a..b2cc55fec21 100644 --- a/org.springframework.context/src/test/java/org/springframework/context/annotation4/SimpleBean.java +++ b/org.springframework.context/src/test/java/org/springframework/context/annotation4/SimpleBean.java @@ -1,36 +1,36 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.context.annotation4; - -import org.springframework.beans.TestBean; -import org.springframework.context.annotation.Bean; - -/** - * Class to test that @FactoryMethods are detected only when inside a class with an @Component - * class annotation. - * - * @author Mark Pollack - */ -public class SimpleBean { - - // This should *not* recognized as a bean since it does not reside inside an @Component - @Bean - public TestBean getPublicInstance() { - return new TestBean("publicInstance"); - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.context.annotation4; + +import org.springframework.beans.TestBean; +import org.springframework.context.annotation.Bean; + +/** + * Class to test that @FactoryMethods are detected only when inside a class with an @Component + * class annotation. + * + * @author Mark Pollack + */ +public class SimpleBean { + + // This should *not* recognized as a bean since it does not reside inside an @Component + @Bean + public TestBean getPublicInstance() { + return new TestBean("publicInstance"); + } + +} diff --git a/org.springframework.context/src/test/java/org/springframework/context/annotation5/MyRepository.java b/org.springframework.context/src/test/java/org/springframework/context/annotation5/MyRepository.java index c7a8094f635..b28fd1a8ea3 100644 --- a/org.springframework.context/src/test/java/org/springframework/context/annotation5/MyRepository.java +++ b/org.springframework.context/src/test/java/org/springframework/context/annotation5/MyRepository.java @@ -1,37 +1,37 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.context.annotation5; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.context.annotation.Lazy; -import org.springframework.context.annotation.Primary; -import org.springframework.stereotype.Repository; - -/** - * @author Juergen Hoeller - */ -@Target({ElementType.TYPE}) -@Retention(RetentionPolicy.RUNTIME) -@Repository -@Primary -@Lazy -public @interface MyRepository { -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.context.annotation5; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.context.annotation.Lazy; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Repository; + +/** + * @author Juergen Hoeller + */ +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Repository +@Primary +@Lazy +public @interface MyRepository { +} diff --git a/org.springframework.context/src/test/java/org/springframework/context/expression/ApplicationContextExpressionTests.java b/org.springframework.context/src/test/java/org/springframework/context/expression/ApplicationContextExpressionTests.java index 7149bbca543..5eac00f54e6 100644 --- a/org.springframework.context/src/test/java/org/springframework/context/expression/ApplicationContextExpressionTests.java +++ b/org.springframework.context/src/test/java/org/springframework/context/expression/ApplicationContextExpressionTests.java @@ -1,432 +1,432 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.context.expression; - -import java.io.Serializable; -import java.security.AccessControlException; -import java.security.Permission; -import java.util.Properties; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import static org.junit.Assert.*; -import org.junit.Test; - -import org.springframework.beans.TestBean; -import org.springframework.beans.factory.ObjectFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer; -import org.springframework.beans.factory.config.Scope; -import org.springframework.beans.factory.config.TypedStringValue; -import org.springframework.beans.factory.support.AutowireCandidateQualifier; -import org.springframework.beans.factory.support.DefaultListableBeanFactory; -import org.springframework.beans.factory.support.GenericBeanDefinition; -import org.springframework.beans.factory.support.RootBeanDefinition; -import org.springframework.context.annotation.AnnotationConfigUtils; -import org.springframework.context.support.GenericApplicationContext; -import org.springframework.util.SerializationTestUtils; -import org.springframework.util.StopWatch; - -/** - * @author Juergen Hoeller - * @since 3.0 - */ -public class ApplicationContextExpressionTests { - - private static final Log factoryLog = LogFactory.getLog(DefaultListableBeanFactory.class); - - @Test - public void genericApplicationContext() throws Exception { - GenericApplicationContext ac = new GenericApplicationContext(); - AnnotationConfigUtils.registerAnnotationConfigProcessors(ac); - - ac.getBeanFactory().registerScope("myScope", new Scope() { - public Object get(String name, ObjectFactory objectFactory) { - return objectFactory.getObject(); - } - public Object remove(String name) { - return null; - } - public void registerDestructionCallback(String name, Runnable callback) { - } - public Object resolveContextualObject(String key) { - if (key.equals("mySpecialAttr")) { - return "42"; - } - else { - return null; - } - } - public String getConversationId() { - return null; - } - }); - - PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer(); - Properties placeholders = new Properties(); - placeholders.setProperty("code", "123"); - ppc.setProperties(placeholders); - ac.addBeanFactoryPostProcessor(ppc); - - GenericBeanDefinition bd0 = new GenericBeanDefinition(); - bd0.setBeanClass(TestBean.class); - bd0.getPropertyValues().add("name", "myName"); - bd0.addQualifier(new AutowireCandidateQualifier(Qualifier.class, "original")); - ac.registerBeanDefinition("tb0", bd0); - - GenericBeanDefinition bd1 = new GenericBeanDefinition(); - bd1.setBeanClass(TestBean.class); - bd1.setScope("myScope"); - bd1.getConstructorArgumentValues().addGenericArgumentValue("XXX#{tb0.name}YYY#{mySpecialAttr}ZZZ"); - bd1.getConstructorArgumentValues().addGenericArgumentValue("#{mySpecialAttr}"); - ac.registerBeanDefinition("tb1", bd1); - - GenericBeanDefinition bd2 = new GenericBeanDefinition(); - bd2.setBeanClass(TestBean.class); - bd2.setScope("myScope"); - bd2.getPropertyValues().add("name", "{ XXX#{tb0.name}YYY#{mySpecialAttr}ZZZ }"); - bd2.getPropertyValues().add("age", "#{mySpecialAttr}"); - bd2.getPropertyValues().add("country", "${code} #{systemProperties.country}"); - ac.registerBeanDefinition("tb2", bd2); - - GenericBeanDefinition bd3 = new GenericBeanDefinition(); - bd3.setBeanClass(ValueTestBean.class); - bd3.setScope("myScope"); - ac.registerBeanDefinition("tb3", bd3); - - GenericBeanDefinition bd4 = new GenericBeanDefinition(); - bd4.setBeanClass(ConstructorValueTestBean.class); - bd4.setScope("myScope"); - ac.registerBeanDefinition("tb4", bd4); - - GenericBeanDefinition bd5 = new GenericBeanDefinition(); - bd5.setBeanClass(MethodValueTestBean.class); - bd5.setScope("myScope"); - ac.registerBeanDefinition("tb5", bd5); - - GenericBeanDefinition bd6 = new GenericBeanDefinition(); - bd6.setBeanClass(PropertyValueTestBean.class); - bd6.setScope("myScope"); - ac.registerBeanDefinition("tb6", bd6); - - System.getProperties().put("country", "UK"); - try { - ac.refresh(); - - TestBean tb0 = ac.getBean("tb0", TestBean.class); - - TestBean tb1 = ac.getBean("tb1", TestBean.class); - assertEquals("XXXmyNameYYY42ZZZ", tb1.getName()); - assertEquals(42, tb1.getAge()); - - TestBean tb2 = ac.getBean("tb2", TestBean.class); - assertEquals("{ XXXmyNameYYY42ZZZ }", tb2.getName()); - assertEquals(42, tb2.getAge()); - assertEquals("123 UK", tb2.getCountry()); - - ValueTestBean tb3 = ac.getBean("tb3", ValueTestBean.class); - assertEquals("XXXmyNameYYY42ZZZ", tb3.name); - assertEquals(42, tb3.age); - assertEquals("123 UK", tb3.country); - assertEquals("123 UK", tb3.countryFactory.getObject()); - System.getProperties().put("country", "US"); - assertEquals("123 UK", tb3.country); - assertEquals("123 US", tb3.countryFactory.getObject()); - System.getProperties().put("country", "UK"); - assertEquals("123 UK", tb3.country); - assertEquals("123 UK", tb3.countryFactory.getObject()); - assertSame(tb0, tb3.tb); - - tb3 = (ValueTestBean) SerializationTestUtils.serializeAndDeserialize(tb3); - assertEquals("123 UK", tb3.countryFactory.getObject()); - - ConstructorValueTestBean tb4 = ac.getBean("tb4", ConstructorValueTestBean.class); - assertEquals("XXXmyNameYYY42ZZZ", tb4.name); - assertEquals(42, tb4.age); - assertEquals("123 UK", tb4.country); - assertSame(tb0, tb4.tb); - - MethodValueTestBean tb5 = ac.getBean("tb5", MethodValueTestBean.class); - assertEquals("XXXmyNameYYY42ZZZ", tb5.name); - assertEquals(42, tb5.age); - assertEquals("123 UK", tb5.country); - assertSame(tb0, tb5.tb); - - PropertyValueTestBean tb6 = ac.getBean("tb6", PropertyValueTestBean.class); - assertEquals("XXXmyNameYYY42ZZZ", tb6.name); - assertEquals(42, tb6.age); - assertEquals("123 UK", tb6.country); - assertSame(tb0, tb6.tb); - } - finally { - System.getProperties().remove("country"); - } - } - - @Test - public void prototypeCreationReevaluatesExpressions() { - GenericApplicationContext ac = new GenericApplicationContext(); - AnnotationConfigUtils.registerAnnotationConfigProcessors(ac); - RootBeanDefinition rbd = new RootBeanDefinition(PrototypeTestBean.class); - rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE); - rbd.getPropertyValues().add("country", "#{systemProperties.country}"); - rbd.getPropertyValues().add("country2", new TypedStringValue("#{systemProperties.country}")); - ac.registerBeanDefinition("test", rbd); - ac.refresh(); - - try { - System.getProperties().put("name", "juergen1"); - System.getProperties().put("country", "UK1"); - PrototypeTestBean tb = (PrototypeTestBean) ac.getBean("test"); - assertEquals("juergen1", tb.getName()); - assertEquals("UK1", tb.getCountry()); - assertEquals("UK1", tb.getCountry2()); - - System.getProperties().put("name", "juergen2"); - System.getProperties().put("country", "UK2"); - tb = (PrototypeTestBean) ac.getBean("test"); - assertEquals("juergen2", tb.getName()); - assertEquals("UK2", tb.getCountry()); - assertEquals("UK2", tb.getCountry2()); - } - finally { - System.getProperties().remove("name"); - System.getProperties().remove("country"); - } - } - - @Test - public void prototypeCreationIsFastEnough() { - if (factoryLog.isTraceEnabled() || factoryLog.isDebugEnabled()) { - // Skip this test: Trace logging blows the time limit. - return; - } - GenericApplicationContext ac = new GenericApplicationContext(); - RootBeanDefinition rbd = new RootBeanDefinition(TestBean.class); - rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE); - rbd.getConstructorArgumentValues().addGenericArgumentValue("#{systemProperties.name}"); - rbd.getPropertyValues().add("country", "#{systemProperties.country}"); - ac.registerBeanDefinition("test", rbd); - ac.refresh(); - StopWatch sw = new StopWatch(); - sw.start("prototype"); - System.getProperties().put("name", "juergen"); - System.getProperties().put("country", "UK"); - try { - for (int i = 0; i < 100000; i++) { - TestBean tb = (TestBean) ac.getBean("test"); - assertEquals("juergen", tb.getName()); - assertEquals("UK", tb.getCountry()); - } - sw.stop(); - } - finally { - System.getProperties().remove("country"); - System.getProperties().remove("name"); - } - assertTrue("Prototype creation took too long: " + sw.getTotalTimeMillis(), sw.getTotalTimeMillis() < 6000); - } - - @Test - public void systemPropertiesSecurityManager() { - GenericApplicationContext ac = new GenericApplicationContext(); - AnnotationConfigUtils.registerAnnotationConfigProcessors(ac); - - GenericBeanDefinition bd = new GenericBeanDefinition(); - bd.setBeanClass(TestBean.class); - bd.getPropertyValues().add("country", "#{systemProperties.country}"); - ac.registerBeanDefinition("tb", bd); - - SecurityManager oldSecurityManager = System.getSecurityManager(); - try { - System.setProperty("country", "NL"); - - SecurityManager securityManager = new SecurityManager() { - @Override - public void checkPropertiesAccess() { - throw new AccessControlException("Not Allowed"); - } - @Override - public void checkPermission(Permission perm) { - // allow everything else - } - }; - System.setSecurityManager(securityManager); - ac.refresh(); - - TestBean tb = ac.getBean("tb", TestBean.class); - assertEquals("NL", tb.getCountry()); - - } - finally { - System.setSecurityManager(oldSecurityManager); - System.getProperties().remove("country"); - } - } - - @Test - public void stringConcatenationWithDebugLogging() { - GenericApplicationContext ac = new GenericApplicationContext(); - AnnotationConfigUtils.registerAnnotationConfigProcessors(ac); - - GenericBeanDefinition bd = new GenericBeanDefinition(); - bd.setBeanClass(String.class); - bd.getConstructorArgumentValues().addGenericArgumentValue("test-#{ T(java.lang.System).currentTimeMillis() }"); - ac.registerBeanDefinition("str", bd); - ac.refresh(); - - String str = ac.getBean("str", String.class); - assertTrue(str.startsWith("test-")); - } - - - public static class ValueTestBean implements Serializable { - - @Autowired @Value("XXX#{tb0.name}YYY#{mySpecialAttr}ZZZ") - public String name; - - @Autowired @Value("#{mySpecialAttr}") - public int age; - - @Value("${code} #{systemProperties.country}") - public String country; - - @Value("${code} #{systemProperties.country}") - public ObjectFactory<String> countryFactory; - - @Autowired @Qualifier("original") - public transient TestBean tb; - } - - - public static class ConstructorValueTestBean { - - public String name; - - public int age; - - public String country; - - public TestBean tb; - - @Autowired - public ConstructorValueTestBean( - @Value("XXX#{tb0.name}YYY#{mySpecialAttr}ZZZ") String name, - @Value("#{mySpecialAttr}") int age, - @Qualifier("original") TestBean tb, - @Value("${code} #{systemProperties.country}") String country) { - this.name = name; - this.age = age; - this.country = country; - this.tb = tb; - } - } - - - public static class MethodValueTestBean { - - public String name; - - public int age; - - public String country; - - public TestBean tb; - - @Autowired - public void configure( - @Qualifier("original") TestBean tb, - @Value("XXX#{tb0.name}YYY#{mySpecialAttr}ZZZ") String name, - @Value("#{mySpecialAttr}") int age, - @Value("${code} #{systemProperties.country}") String country) { - this.name = name; - this.age = age; - this.country = country; - this.tb = tb; - } - } - - - public static class PropertyValueTestBean { - - public String name; - - public int age; - - public String country; - - public TestBean tb; - - @Value("XXX#{tb0.name}YYY#{mySpecialAttr}ZZZ") - public void setName(String name) { - this.name = name; - } - - @Value("#{mySpecialAttr}") - public void setAge(int age) { - this.age = age; - } - - @Value("${code} #{systemProperties.country}") - public void setCountry(String country) { - this.country = country; - } - - @Autowired @Qualifier("original") - public void setTb(TestBean tb) { - this.tb = tb; - } - } - - - public static class PrototypeTestBean { - - public String name; - - public String country; - - public String country2; - - @Value("#{systemProperties.name}") - public void setName(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - public void setCountry(String country) { - this.country = country; - } - - public String getCountry() { - return country; - } - - public void setCountry2(String country2) { - this.country2 = country2; - } - - public String getCountry2() { - return country2; - } - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.context.expression; + +import java.io.Serializable; +import java.security.AccessControlException; +import java.security.Permission; +import java.util.Properties; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import static org.junit.Assert.*; +import org.junit.Test; + +import org.springframework.beans.TestBean; +import org.springframework.beans.factory.ObjectFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer; +import org.springframework.beans.factory.config.Scope; +import org.springframework.beans.factory.config.TypedStringValue; +import org.springframework.beans.factory.support.AutowireCandidateQualifier; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.beans.factory.support.GenericBeanDefinition; +import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.context.annotation.AnnotationConfigUtils; +import org.springframework.context.support.GenericApplicationContext; +import org.springframework.util.SerializationTestUtils; +import org.springframework.util.StopWatch; + +/** + * @author Juergen Hoeller + * @since 3.0 + */ +public class ApplicationContextExpressionTests { + + private static final Log factoryLog = LogFactory.getLog(DefaultListableBeanFactory.class); + + @Test + public void genericApplicationContext() throws Exception { + GenericApplicationContext ac = new GenericApplicationContext(); + AnnotationConfigUtils.registerAnnotationConfigProcessors(ac); + + ac.getBeanFactory().registerScope("myScope", new Scope() { + public Object get(String name, ObjectFactory objectFactory) { + return objectFactory.getObject(); + } + public Object remove(String name) { + return null; + } + public void registerDestructionCallback(String name, Runnable callback) { + } + public Object resolveContextualObject(String key) { + if (key.equals("mySpecialAttr")) { + return "42"; + } + else { + return null; + } + } + public String getConversationId() { + return null; + } + }); + + PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer(); + Properties placeholders = new Properties(); + placeholders.setProperty("code", "123"); + ppc.setProperties(placeholders); + ac.addBeanFactoryPostProcessor(ppc); + + GenericBeanDefinition bd0 = new GenericBeanDefinition(); + bd0.setBeanClass(TestBean.class); + bd0.getPropertyValues().add("name", "myName"); + bd0.addQualifier(new AutowireCandidateQualifier(Qualifier.class, "original")); + ac.registerBeanDefinition("tb0", bd0); + + GenericBeanDefinition bd1 = new GenericBeanDefinition(); + bd1.setBeanClass(TestBean.class); + bd1.setScope("myScope"); + bd1.getConstructorArgumentValues().addGenericArgumentValue("XXX#{tb0.name}YYY#{mySpecialAttr}ZZZ"); + bd1.getConstructorArgumentValues().addGenericArgumentValue("#{mySpecialAttr}"); + ac.registerBeanDefinition("tb1", bd1); + + GenericBeanDefinition bd2 = new GenericBeanDefinition(); + bd2.setBeanClass(TestBean.class); + bd2.setScope("myScope"); + bd2.getPropertyValues().add("name", "{ XXX#{tb0.name}YYY#{mySpecialAttr}ZZZ }"); + bd2.getPropertyValues().add("age", "#{mySpecialAttr}"); + bd2.getPropertyValues().add("country", "${code} #{systemProperties.country}"); + ac.registerBeanDefinition("tb2", bd2); + + GenericBeanDefinition bd3 = new GenericBeanDefinition(); + bd3.setBeanClass(ValueTestBean.class); + bd3.setScope("myScope"); + ac.registerBeanDefinition("tb3", bd3); + + GenericBeanDefinition bd4 = new GenericBeanDefinition(); + bd4.setBeanClass(ConstructorValueTestBean.class); + bd4.setScope("myScope"); + ac.registerBeanDefinition("tb4", bd4); + + GenericBeanDefinition bd5 = new GenericBeanDefinition(); + bd5.setBeanClass(MethodValueTestBean.class); + bd5.setScope("myScope"); + ac.registerBeanDefinition("tb5", bd5); + + GenericBeanDefinition bd6 = new GenericBeanDefinition(); + bd6.setBeanClass(PropertyValueTestBean.class); + bd6.setScope("myScope"); + ac.registerBeanDefinition("tb6", bd6); + + System.getProperties().put("country", "UK"); + try { + ac.refresh(); + + TestBean tb0 = ac.getBean("tb0", TestBean.class); + + TestBean tb1 = ac.getBean("tb1", TestBean.class); + assertEquals("XXXmyNameYYY42ZZZ", tb1.getName()); + assertEquals(42, tb1.getAge()); + + TestBean tb2 = ac.getBean("tb2", TestBean.class); + assertEquals("{ XXXmyNameYYY42ZZZ }", tb2.getName()); + assertEquals(42, tb2.getAge()); + assertEquals("123 UK", tb2.getCountry()); + + ValueTestBean tb3 = ac.getBean("tb3", ValueTestBean.class); + assertEquals("XXXmyNameYYY42ZZZ", tb3.name); + assertEquals(42, tb3.age); + assertEquals("123 UK", tb3.country); + assertEquals("123 UK", tb3.countryFactory.getObject()); + System.getProperties().put("country", "US"); + assertEquals("123 UK", tb3.country); + assertEquals("123 US", tb3.countryFactory.getObject()); + System.getProperties().put("country", "UK"); + assertEquals("123 UK", tb3.country); + assertEquals("123 UK", tb3.countryFactory.getObject()); + assertSame(tb0, tb3.tb); + + tb3 = (ValueTestBean) SerializationTestUtils.serializeAndDeserialize(tb3); + assertEquals("123 UK", tb3.countryFactory.getObject()); + + ConstructorValueTestBean tb4 = ac.getBean("tb4", ConstructorValueTestBean.class); + assertEquals("XXXmyNameYYY42ZZZ", tb4.name); + assertEquals(42, tb4.age); + assertEquals("123 UK", tb4.country); + assertSame(tb0, tb4.tb); + + MethodValueTestBean tb5 = ac.getBean("tb5", MethodValueTestBean.class); + assertEquals("XXXmyNameYYY42ZZZ", tb5.name); + assertEquals(42, tb5.age); + assertEquals("123 UK", tb5.country); + assertSame(tb0, tb5.tb); + + PropertyValueTestBean tb6 = ac.getBean("tb6", PropertyValueTestBean.class); + assertEquals("XXXmyNameYYY42ZZZ", tb6.name); + assertEquals(42, tb6.age); + assertEquals("123 UK", tb6.country); + assertSame(tb0, tb6.tb); + } + finally { + System.getProperties().remove("country"); + } + } + + @Test + public void prototypeCreationReevaluatesExpressions() { + GenericApplicationContext ac = new GenericApplicationContext(); + AnnotationConfigUtils.registerAnnotationConfigProcessors(ac); + RootBeanDefinition rbd = new RootBeanDefinition(PrototypeTestBean.class); + rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE); + rbd.getPropertyValues().add("country", "#{systemProperties.country}"); + rbd.getPropertyValues().add("country2", new TypedStringValue("#{systemProperties.country}")); + ac.registerBeanDefinition("test", rbd); + ac.refresh(); + + try { + System.getProperties().put("name", "juergen1"); + System.getProperties().put("country", "UK1"); + PrototypeTestBean tb = (PrototypeTestBean) ac.getBean("test"); + assertEquals("juergen1", tb.getName()); + assertEquals("UK1", tb.getCountry()); + assertEquals("UK1", tb.getCountry2()); + + System.getProperties().put("name", "juergen2"); + System.getProperties().put("country", "UK2"); + tb = (PrototypeTestBean) ac.getBean("test"); + assertEquals("juergen2", tb.getName()); + assertEquals("UK2", tb.getCountry()); + assertEquals("UK2", tb.getCountry2()); + } + finally { + System.getProperties().remove("name"); + System.getProperties().remove("country"); + } + } + + @Test + public void prototypeCreationIsFastEnough() { + if (factoryLog.isTraceEnabled() || factoryLog.isDebugEnabled()) { + // Skip this test: Trace logging blows the time limit. + return; + } + GenericApplicationContext ac = new GenericApplicationContext(); + RootBeanDefinition rbd = new RootBeanDefinition(TestBean.class); + rbd.setScope(RootBeanDefinition.SCOPE_PROTOTYPE); + rbd.getConstructorArgumentValues().addGenericArgumentValue("#{systemProperties.name}"); + rbd.getPropertyValues().add("country", "#{systemProperties.country}"); + ac.registerBeanDefinition("test", rbd); + ac.refresh(); + StopWatch sw = new StopWatch(); + sw.start("prototype"); + System.getProperties().put("name", "juergen"); + System.getProperties().put("country", "UK"); + try { + for (int i = 0; i < 100000; i++) { + TestBean tb = (TestBean) ac.getBean("test"); + assertEquals("juergen", tb.getName()); + assertEquals("UK", tb.getCountry()); + } + sw.stop(); + } + finally { + System.getProperties().remove("country"); + System.getProperties().remove("name"); + } + assertTrue("Prototype creation took too long: " + sw.getTotalTimeMillis(), sw.getTotalTimeMillis() < 6000); + } + + @Test + public void systemPropertiesSecurityManager() { + GenericApplicationContext ac = new GenericApplicationContext(); + AnnotationConfigUtils.registerAnnotationConfigProcessors(ac); + + GenericBeanDefinition bd = new GenericBeanDefinition(); + bd.setBeanClass(TestBean.class); + bd.getPropertyValues().add("country", "#{systemProperties.country}"); + ac.registerBeanDefinition("tb", bd); + + SecurityManager oldSecurityManager = System.getSecurityManager(); + try { + System.setProperty("country", "NL"); + + SecurityManager securityManager = new SecurityManager() { + @Override + public void checkPropertiesAccess() { + throw new AccessControlException("Not Allowed"); + } + @Override + public void checkPermission(Permission perm) { + // allow everything else + } + }; + System.setSecurityManager(securityManager); + ac.refresh(); + + TestBean tb = ac.getBean("tb", TestBean.class); + assertEquals("NL", tb.getCountry()); + + } + finally { + System.setSecurityManager(oldSecurityManager); + System.getProperties().remove("country"); + } + } + + @Test + public void stringConcatenationWithDebugLogging() { + GenericApplicationContext ac = new GenericApplicationContext(); + AnnotationConfigUtils.registerAnnotationConfigProcessors(ac); + + GenericBeanDefinition bd = new GenericBeanDefinition(); + bd.setBeanClass(String.class); + bd.getConstructorArgumentValues().addGenericArgumentValue("test-#{ T(java.lang.System).currentTimeMillis() }"); + ac.registerBeanDefinition("str", bd); + ac.refresh(); + + String str = ac.getBean("str", String.class); + assertTrue(str.startsWith("test-")); + } + + + public static class ValueTestBean implements Serializable { + + @Autowired @Value("XXX#{tb0.name}YYY#{mySpecialAttr}ZZZ") + public String name; + + @Autowired @Value("#{mySpecialAttr}") + public int age; + + @Value("${code} #{systemProperties.country}") + public String country; + + @Value("${code} #{systemProperties.country}") + public ObjectFactory<String> countryFactory; + + @Autowired @Qualifier("original") + public transient TestBean tb; + } + + + public static class ConstructorValueTestBean { + + public String name; + + public int age; + + public String country; + + public TestBean tb; + + @Autowired + public ConstructorValueTestBean( + @Value("XXX#{tb0.name}YYY#{mySpecialAttr}ZZZ") String name, + @Value("#{mySpecialAttr}") int age, + @Qualifier("original") TestBean tb, + @Value("${code} #{systemProperties.country}") String country) { + this.name = name; + this.age = age; + this.country = country; + this.tb = tb; + } + } + + + public static class MethodValueTestBean { + + public String name; + + public int age; + + public String country; + + public TestBean tb; + + @Autowired + public void configure( + @Qualifier("original") TestBean tb, + @Value("XXX#{tb0.name}YYY#{mySpecialAttr}ZZZ") String name, + @Value("#{mySpecialAttr}") int age, + @Value("${code} #{systemProperties.country}") String country) { + this.name = name; + this.age = age; + this.country = country; + this.tb = tb; + } + } + + + public static class PropertyValueTestBean { + + public String name; + + public int age; + + public String country; + + public TestBean tb; + + @Value("XXX#{tb0.name}YYY#{mySpecialAttr}ZZZ") + public void setName(String name) { + this.name = name; + } + + @Value("#{mySpecialAttr}") + public void setAge(int age) { + this.age = age; + } + + @Value("${code} #{systemProperties.country}") + public void setCountry(String country) { + this.country = country; + } + + @Autowired @Qualifier("original") + public void setTb(TestBean tb) { + this.tb = tb; + } + } + + + public static class PrototypeTestBean { + + public String name; + + public String country; + + public String country2; + + @Value("#{systemProperties.name}") + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setCountry(String country) { + this.country = country; + } + + public String getCountry() { + return country; + } + + public void setCountry2(String country2) { + this.country2 = country2; + } + + public String getCountry2() { + return country2; + } + } + +} diff --git a/org.springframework.context/src/test/java/org/springframework/context/support/GenericApplicationContextTests.java b/org.springframework.context/src/test/java/org/springframework/context/support/GenericApplicationContextTests.java index 67b3f54c7d4..8587ff38ced 100644 --- a/org.springframework.context/src/test/java/org/springframework/context/support/GenericApplicationContextTests.java +++ b/org.springframework.context/src/test/java/org/springframework/context/support/GenericApplicationContextTests.java @@ -1,36 +1,36 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.context.support; - -import org.junit.Test; - -import org.springframework.beans.factory.support.DefaultListableBeanFactory; - -/** - * @author Juergen Hoeller - * @author Chris Beams - */ -public class GenericApplicationContextTests { - - @Test - public void nullBeanRegistration() { - DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); - bf.registerSingleton("nullBean", null); - new GenericApplicationContext(bf).refresh(); - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.context.support; + +import org.junit.Test; + +import org.springframework.beans.factory.support.DefaultListableBeanFactory; + +/** + * @author Juergen Hoeller + * @author Chris Beams + */ +public class GenericApplicationContextTests { + + @Test + public void nullBeanRegistration() { + DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); + bf.registerSingleton("nullBean", null); + new GenericApplicationContext(bf).refresh(); + } + +} diff --git a/org.springframework.context/src/test/java/org/springframework/context/support/ResourceConverter.java b/org.springframework.context/src/test/java/org/springframework/context/support/ResourceConverter.java index 84236dae1db..f5834e8e6f6 100644 --- a/org.springframework.context/src/test/java/org/springframework/context/support/ResourceConverter.java +++ b/org.springframework.context/src/test/java/org/springframework/context/support/ResourceConverter.java @@ -1,32 +1,32 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.context.support; - -import org.springframework.core.convert.converter.Converter; -import org.springframework.core.io.FileSystemResource; -import org.springframework.core.io.Resource; - -/** - * @author Juergen Hoeller - */ -public class ResourceConverter implements Converter<String, Resource> { - - public Resource convert(String source) { - return new FileSystemResource(source + ".xml"); - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.context.support; + +import org.springframework.core.convert.converter.Converter; +import org.springframework.core.io.FileSystemResource; +import org.springframework.core.io.Resource; + +/** + * @author Juergen Hoeller + */ +public class ResourceConverter implements Converter<String, Resource> { + + public Resource convert(String source) { + return new FileSystemResource(source + ".xml"); + } + +} diff --git a/org.springframework.context/src/test/java/org/springframework/context/support/Spr7283Tests.java b/org.springframework.context/src/test/java/org/springframework/context/support/Spr7283Tests.java index c6ecdd41605..40255c0e684 100644 --- a/org.springframework.context/src/test/java/org/springframework/context/support/Spr7283Tests.java +++ b/org.springframework.context/src/test/java/org/springframework/context/support/Spr7283Tests.java @@ -1,48 +1,48 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.context.support; - -import java.util.List; - -import static org.junit.Assert.*; -import org.junit.Test; - -/** - * @author Scott Andrews - * @author Juergen Hoeller - */ -public class Spr7283Tests { - - @Test - public void testListWithInconsistentElementType() { - ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("spr7283.xml", getClass()); - List list = ctx.getBean("list", List.class); - assertEquals(2, list.size()); - assertTrue(list.get(0) instanceof A); - assertTrue(list.get(1) instanceof B); - } - - - public static class A { - public A() {} - } - - public static class B { - public B() {} - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.context.support; + +import java.util.List; + +import static org.junit.Assert.*; +import org.junit.Test; + +/** + * @author Scott Andrews + * @author Juergen Hoeller + */ +public class Spr7283Tests { + + @Test + public void testListWithInconsistentElementType() { + ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("spr7283.xml", getClass()); + List list = ctx.getBean("list", List.class); + assertEquals(2, list.size()); + assertTrue(list.get(0) instanceof A); + assertTrue(list.get(1) instanceof B); + } + + + public static class A { + public A() {} + } + + public static class B { + public B() {} + } + +} diff --git a/org.springframework.context/src/test/java/org/springframework/jmx/export/annotation/AnnotationTestBeanFactory.java b/org.springframework.context/src/test/java/org/springframework/jmx/export/annotation/AnnotationTestBeanFactory.java index c8b71e2b610..c94cb07e06c 100644 --- a/org.springframework.context/src/test/java/org/springframework/jmx/export/annotation/AnnotationTestBeanFactory.java +++ b/org.springframework.context/src/test/java/org/springframework/jmx/export/annotation/AnnotationTestBeanFactory.java @@ -1,45 +1,45 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jmx.export.annotation; - -import org.springframework.beans.factory.FactoryBean; -import org.springframework.jmx.IJmxTestBean; - -/** - * @author Juergen Hoeller - */ -public class AnnotationTestBeanFactory implements FactoryBean<IJmxTestBean> { - - private final FactoryCreatedAnnotationTestBean instance = new FactoryCreatedAnnotationTestBean(); - - public AnnotationTestBeanFactory() { - this.instance.setName("FACTORY"); - } - - public IJmxTestBean getObject() throws Exception { - return this.instance; - } - - public Class<? extends IJmxTestBean> getObjectType() { - return FactoryCreatedAnnotationTestBean.class; - } - - public boolean isSingleton() { - return true; - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.jmx.export.annotation; + +import org.springframework.beans.factory.FactoryBean; +import org.springframework.jmx.IJmxTestBean; + +/** + * @author Juergen Hoeller + */ +public class AnnotationTestBeanFactory implements FactoryBean<IJmxTestBean> { + + private final FactoryCreatedAnnotationTestBean instance = new FactoryCreatedAnnotationTestBean(); + + public AnnotationTestBeanFactory() { + this.instance.setName("FACTORY"); + } + + public IJmxTestBean getObject() throws Exception { + return this.instance; + } + + public Class<? extends IJmxTestBean> getObjectType() { + return FactoryCreatedAnnotationTestBean.class; + } + + public boolean isSingleton() { + return true; + } + +} diff --git a/org.springframework.context/src/test/java/org/springframework/jmx/export/annotation/FactoryCreatedAnnotationTestBean.java b/org.springframework.context/src/test/java/org/springframework/jmx/export/annotation/FactoryCreatedAnnotationTestBean.java index a8a9b3f6706..2741a8b97c0 100644 --- a/org.springframework.context/src/test/java/org/springframework/jmx/export/annotation/FactoryCreatedAnnotationTestBean.java +++ b/org.springframework.context/src/test/java/org/springframework/jmx/export/annotation/FactoryCreatedAnnotationTestBean.java @@ -1,25 +1,25 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jmx.export.annotation; - -/** - * @author Juergen Hoeller - */ -@ManagedResource(objectName = "bean:name=testBean5") -public class FactoryCreatedAnnotationTestBean extends AnnotationTestBean { - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.jmx.export.annotation; + +/** + * @author Juergen Hoeller + */ +@ManagedResource(objectName = "bean:name=testBean5") +public class FactoryCreatedAnnotationTestBean extends AnnotationTestBean { + +} diff --git a/org.springframework.context/src/test/java/org/springframework/scheduling/annotation/AsyncExecutionTests.java b/org.springframework.context/src/test/java/org/springframework/scheduling/annotation/AsyncExecutionTests.java index 9dbc91f7e9f..da4436b35e1 100644 --- a/org.springframework.context/src/test/java/org/springframework/scheduling/annotation/AsyncExecutionTests.java +++ b/org.springframework.context/src/test/java/org/springframework/scheduling/annotation/AsyncExecutionTests.java @@ -1,261 +1,261 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.scheduling.annotation; - -import java.util.concurrent.Future; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import org.junit.Test; - -import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; -import org.springframework.beans.factory.support.RootBeanDefinition; -import org.springframework.context.ApplicationEvent; -import org.springframework.context.ApplicationListener; -import org.springframework.context.support.GenericApplicationContext; -import org.springframework.scheduling.annotation.AsyncResult; - -/** - * @author Juergen Hoeller - */ -public class AsyncExecutionTests { - - private static String originalThreadName; - - private static int listenerCalled = 0; - - private static int listenerConstructed = 0; - - - @Test - public void asyncMethods() throws Exception { - originalThreadName = Thread.currentThread().getName(); - GenericApplicationContext context = new GenericApplicationContext(); - context.registerBeanDefinition("asyncTest", new RootBeanDefinition(AsyncMethodBean.class)); - context.registerBeanDefinition("autoProxyCreator", new RootBeanDefinition(DefaultAdvisorAutoProxyCreator.class)); - context.registerBeanDefinition("asyncAdvisor", new RootBeanDefinition(AsyncAnnotationAdvisor.class)); - context.refresh(); - AsyncMethodBean asyncTest = context.getBean("asyncTest", AsyncMethodBean.class); - asyncTest.doNothing(5); - asyncTest.doSomething(10); - Future<String> future = asyncTest.returnSomething(20); - assertEquals("20", future.get()); - } - - @Test - public void asyncClass() throws Exception { - originalThreadName = Thread.currentThread().getName(); - GenericApplicationContext context = new GenericApplicationContext(); - context.registerBeanDefinition("asyncTest", new RootBeanDefinition(AsyncClassBean.class)); - context.registerBeanDefinition("autoProxyCreator", new RootBeanDefinition(DefaultAdvisorAutoProxyCreator.class)); - context.registerBeanDefinition("asyncAdvisor", new RootBeanDefinition(AsyncAnnotationAdvisor.class)); - context.refresh(); - AsyncClassBean asyncTest = context.getBean("asyncTest", AsyncClassBean.class); - asyncTest.doSomething(10); - Future<String> future = asyncTest.returnSomething(20); - assertEquals("20", future.get()); - } - - @Test - public void asyncInterface() throws Exception { - originalThreadName = Thread.currentThread().getName(); - GenericApplicationContext context = new GenericApplicationContext(); - context.registerBeanDefinition("asyncTest", new RootBeanDefinition(AsyncInterfaceBean.class)); - context.registerBeanDefinition("autoProxyCreator", new RootBeanDefinition(DefaultAdvisorAutoProxyCreator.class)); - context.registerBeanDefinition("asyncAdvisor", new RootBeanDefinition(AsyncAnnotationAdvisor.class)); - context.refresh(); - AsyncInterface asyncTest = context.getBean("asyncTest", AsyncInterface.class); - asyncTest.doSomething(10); - Future<String> future = asyncTest.returnSomething(20); - assertEquals("20", future.get()); - } - - @Test - public void asyncMethodsInInterface() throws Exception { - originalThreadName = Thread.currentThread().getName(); - GenericApplicationContext context = new GenericApplicationContext(); - context.registerBeanDefinition("asyncTest", new RootBeanDefinition(AsyncMethodsInterfaceBean.class)); - context.registerBeanDefinition("autoProxyCreator", new RootBeanDefinition(DefaultAdvisorAutoProxyCreator.class)); - context.registerBeanDefinition("asyncAdvisor", new RootBeanDefinition(AsyncAnnotationAdvisor.class)); - context.refresh(); - AsyncMethodsInterface asyncTest = context.getBean("asyncTest", AsyncMethodsInterface.class); - asyncTest.doNothing(5); - asyncTest.doSomething(10); - Future<String> future = asyncTest.returnSomething(20); - assertEquals("20", future.get()); - } - - @Test - public void asyncMethodListener() throws Exception { - originalThreadName = Thread.currentThread().getName(); - listenerCalled = 0; - GenericApplicationContext context = new GenericApplicationContext(); - context.registerBeanDefinition("asyncTest", new RootBeanDefinition(AsyncMethodListener.class)); - context.registerBeanDefinition("autoProxyCreator", new RootBeanDefinition(DefaultAdvisorAutoProxyCreator.class)); - context.registerBeanDefinition("asyncAdvisor", new RootBeanDefinition(AsyncAnnotationAdvisor.class)); - context.refresh(); - Thread.sleep(1000); - assertEquals(1, listenerCalled); - } - - @Test - public void asyncClassListener() throws Exception { - originalThreadName = Thread.currentThread().getName(); - listenerCalled = 0; - listenerConstructed = 0; - GenericApplicationContext context = new GenericApplicationContext(); - context.registerBeanDefinition("asyncTest", new RootBeanDefinition(AsyncClassListener.class)); - context.registerBeanDefinition("autoProxyCreator", new RootBeanDefinition(DefaultAdvisorAutoProxyCreator.class)); - context.registerBeanDefinition("asyncAdvisor", new RootBeanDefinition(AsyncAnnotationAdvisor.class)); - context.refresh(); - context.close(); - Thread.sleep(1000); - assertEquals(2, listenerCalled); - assertEquals(1, listenerConstructed); - } - - @Test - public void asyncPrototypeClassListener() throws Exception { - originalThreadName = Thread.currentThread().getName(); - listenerCalled = 0; - listenerConstructed = 0; - GenericApplicationContext context = new GenericApplicationContext(); - RootBeanDefinition listenerDef = new RootBeanDefinition(AsyncClassListener.class); - listenerDef.setScope(RootBeanDefinition.SCOPE_PROTOTYPE); - context.registerBeanDefinition("asyncTest", listenerDef); - context.registerBeanDefinition("autoProxyCreator", new RootBeanDefinition(DefaultAdvisorAutoProxyCreator.class)); - context.registerBeanDefinition("asyncAdvisor", new RootBeanDefinition(AsyncAnnotationAdvisor.class)); - context.refresh(); - context.close(); - Thread.sleep(1000); - assertEquals(2, listenerCalled); - assertEquals(2, listenerConstructed); - } - - - public static class AsyncMethodBean { - - public void doNothing(int i) { - assertTrue(Thread.currentThread().getName().equals(originalThreadName)); - } - - @Async - public void doSomething(int i) { - System.out.println(Thread.currentThread().getName() + ": " + i); - assertTrue(!Thread.currentThread().getName().equals(originalThreadName)); - } - - @Async - public Future<String> returnSomething(int i) { - assertTrue(!Thread.currentThread().getName().equals(originalThreadName)); - return new AsyncResult<String>(Integer.toString(i)); - } - } - - - @Async - public static class AsyncClassBean { - - public void doSomething(int i) { - System.out.println(Thread.currentThread().getName() + ": " + i); - assertTrue(!Thread.currentThread().getName().equals(originalThreadName)); - } - - public Future<String> returnSomething(int i) { - assertTrue(!Thread.currentThread().getName().equals(originalThreadName)); - return new AsyncResult<String>(Integer.toString(i)); - } - } - - - @Async - public interface AsyncInterface { - - void doSomething(int i); - - Future<String> returnSomething(int i); - } - - - public static class AsyncInterfaceBean implements AsyncInterface { - - public void doSomething(int i) { - System.out.println(Thread.currentThread().getName() + ": " + i); - assertTrue(!Thread.currentThread().getName().equals(originalThreadName)); - } - - public Future<String> returnSomething(int i) { - assertTrue(!Thread.currentThread().getName().equals(originalThreadName)); - return new AsyncResult<String>(Integer.toString(i)); - } - } - - - public interface AsyncMethodsInterface { - - void doNothing(int i); - - @Async - void doSomething(int i); - - @Async - Future<String> returnSomething(int i); - } - - - public static class AsyncMethodsInterfaceBean implements AsyncMethodsInterface { - - public void doNothing(int i) { - assertTrue(Thread.currentThread().getName().equals(originalThreadName)); - } - - public void doSomething(int i) { - System.out.println(Thread.currentThread().getName() + ": " + i); - assertTrue(!Thread.currentThread().getName().equals(originalThreadName)); - } - - public Future<String> returnSomething(int i) { - assertTrue(!Thread.currentThread().getName().equals(originalThreadName)); - return new AsyncResult<String>(Integer.toString(i)); - } - } - - - public static class AsyncMethodListener implements ApplicationListener { - - @Async - public void onApplicationEvent(ApplicationEvent event) { - listenerCalled++; - assertTrue(!Thread.currentThread().getName().equals(originalThreadName)); - } - } - - - @Async - public static class AsyncClassListener implements ApplicationListener { - - public AsyncClassListener() { - listenerConstructed++; - } - - public void onApplicationEvent(ApplicationEvent event) { - listenerCalled++; - assertTrue(!Thread.currentThread().getName().equals(originalThreadName)); - } - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.scheduling.annotation; + +import java.util.concurrent.Future; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import org.junit.Test; + +import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; +import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.context.ApplicationEvent; +import org.springframework.context.ApplicationListener; +import org.springframework.context.support.GenericApplicationContext; +import org.springframework.scheduling.annotation.AsyncResult; + +/** + * @author Juergen Hoeller + */ +public class AsyncExecutionTests { + + private static String originalThreadName; + + private static int listenerCalled = 0; + + private static int listenerConstructed = 0; + + + @Test + public void asyncMethods() throws Exception { + originalThreadName = Thread.currentThread().getName(); + GenericApplicationContext context = new GenericApplicationContext(); + context.registerBeanDefinition("asyncTest", new RootBeanDefinition(AsyncMethodBean.class)); + context.registerBeanDefinition("autoProxyCreator", new RootBeanDefinition(DefaultAdvisorAutoProxyCreator.class)); + context.registerBeanDefinition("asyncAdvisor", new RootBeanDefinition(AsyncAnnotationAdvisor.class)); + context.refresh(); + AsyncMethodBean asyncTest = context.getBean("asyncTest", AsyncMethodBean.class); + asyncTest.doNothing(5); + asyncTest.doSomething(10); + Future<String> future = asyncTest.returnSomething(20); + assertEquals("20", future.get()); + } + + @Test + public void asyncClass() throws Exception { + originalThreadName = Thread.currentThread().getName(); + GenericApplicationContext context = new GenericApplicationContext(); + context.registerBeanDefinition("asyncTest", new RootBeanDefinition(AsyncClassBean.class)); + context.registerBeanDefinition("autoProxyCreator", new RootBeanDefinition(DefaultAdvisorAutoProxyCreator.class)); + context.registerBeanDefinition("asyncAdvisor", new RootBeanDefinition(AsyncAnnotationAdvisor.class)); + context.refresh(); + AsyncClassBean asyncTest = context.getBean("asyncTest", AsyncClassBean.class); + asyncTest.doSomething(10); + Future<String> future = asyncTest.returnSomething(20); + assertEquals("20", future.get()); + } + + @Test + public void asyncInterface() throws Exception { + originalThreadName = Thread.currentThread().getName(); + GenericApplicationContext context = new GenericApplicationContext(); + context.registerBeanDefinition("asyncTest", new RootBeanDefinition(AsyncInterfaceBean.class)); + context.registerBeanDefinition("autoProxyCreator", new RootBeanDefinition(DefaultAdvisorAutoProxyCreator.class)); + context.registerBeanDefinition("asyncAdvisor", new RootBeanDefinition(AsyncAnnotationAdvisor.class)); + context.refresh(); + AsyncInterface asyncTest = context.getBean("asyncTest", AsyncInterface.class); + asyncTest.doSomething(10); + Future<String> future = asyncTest.returnSomething(20); + assertEquals("20", future.get()); + } + + @Test + public void asyncMethodsInInterface() throws Exception { + originalThreadName = Thread.currentThread().getName(); + GenericApplicationContext context = new GenericApplicationContext(); + context.registerBeanDefinition("asyncTest", new RootBeanDefinition(AsyncMethodsInterfaceBean.class)); + context.registerBeanDefinition("autoProxyCreator", new RootBeanDefinition(DefaultAdvisorAutoProxyCreator.class)); + context.registerBeanDefinition("asyncAdvisor", new RootBeanDefinition(AsyncAnnotationAdvisor.class)); + context.refresh(); + AsyncMethodsInterface asyncTest = context.getBean("asyncTest", AsyncMethodsInterface.class); + asyncTest.doNothing(5); + asyncTest.doSomething(10); + Future<String> future = asyncTest.returnSomething(20); + assertEquals("20", future.get()); + } + + @Test + public void asyncMethodListener() throws Exception { + originalThreadName = Thread.currentThread().getName(); + listenerCalled = 0; + GenericApplicationContext context = new GenericApplicationContext(); + context.registerBeanDefinition("asyncTest", new RootBeanDefinition(AsyncMethodListener.class)); + context.registerBeanDefinition("autoProxyCreator", new RootBeanDefinition(DefaultAdvisorAutoProxyCreator.class)); + context.registerBeanDefinition("asyncAdvisor", new RootBeanDefinition(AsyncAnnotationAdvisor.class)); + context.refresh(); + Thread.sleep(1000); + assertEquals(1, listenerCalled); + } + + @Test + public void asyncClassListener() throws Exception { + originalThreadName = Thread.currentThread().getName(); + listenerCalled = 0; + listenerConstructed = 0; + GenericApplicationContext context = new GenericApplicationContext(); + context.registerBeanDefinition("asyncTest", new RootBeanDefinition(AsyncClassListener.class)); + context.registerBeanDefinition("autoProxyCreator", new RootBeanDefinition(DefaultAdvisorAutoProxyCreator.class)); + context.registerBeanDefinition("asyncAdvisor", new RootBeanDefinition(AsyncAnnotationAdvisor.class)); + context.refresh(); + context.close(); + Thread.sleep(1000); + assertEquals(2, listenerCalled); + assertEquals(1, listenerConstructed); + } + + @Test + public void asyncPrototypeClassListener() throws Exception { + originalThreadName = Thread.currentThread().getName(); + listenerCalled = 0; + listenerConstructed = 0; + GenericApplicationContext context = new GenericApplicationContext(); + RootBeanDefinition listenerDef = new RootBeanDefinition(AsyncClassListener.class); + listenerDef.setScope(RootBeanDefinition.SCOPE_PROTOTYPE); + context.registerBeanDefinition("asyncTest", listenerDef); + context.registerBeanDefinition("autoProxyCreator", new RootBeanDefinition(DefaultAdvisorAutoProxyCreator.class)); + context.registerBeanDefinition("asyncAdvisor", new RootBeanDefinition(AsyncAnnotationAdvisor.class)); + context.refresh(); + context.close(); + Thread.sleep(1000); + assertEquals(2, listenerCalled); + assertEquals(2, listenerConstructed); + } + + + public static class AsyncMethodBean { + + public void doNothing(int i) { + assertTrue(Thread.currentThread().getName().equals(originalThreadName)); + } + + @Async + public void doSomething(int i) { + System.out.println(Thread.currentThread().getName() + ": " + i); + assertTrue(!Thread.currentThread().getName().equals(originalThreadName)); + } + + @Async + public Future<String> returnSomething(int i) { + assertTrue(!Thread.currentThread().getName().equals(originalThreadName)); + return new AsyncResult<String>(Integer.toString(i)); + } + } + + + @Async + public static class AsyncClassBean { + + public void doSomething(int i) { + System.out.println(Thread.currentThread().getName() + ": " + i); + assertTrue(!Thread.currentThread().getName().equals(originalThreadName)); + } + + public Future<String> returnSomething(int i) { + assertTrue(!Thread.currentThread().getName().equals(originalThreadName)); + return new AsyncResult<String>(Integer.toString(i)); + } + } + + + @Async + public interface AsyncInterface { + + void doSomething(int i); + + Future<String> returnSomething(int i); + } + + + public static class AsyncInterfaceBean implements AsyncInterface { + + public void doSomething(int i) { + System.out.println(Thread.currentThread().getName() + ": " + i); + assertTrue(!Thread.currentThread().getName().equals(originalThreadName)); + } + + public Future<String> returnSomething(int i) { + assertTrue(!Thread.currentThread().getName().equals(originalThreadName)); + return new AsyncResult<String>(Integer.toString(i)); + } + } + + + public interface AsyncMethodsInterface { + + void doNothing(int i); + + @Async + void doSomething(int i); + + @Async + Future<String> returnSomething(int i); + } + + + public static class AsyncMethodsInterfaceBean implements AsyncMethodsInterface { + + public void doNothing(int i) { + assertTrue(Thread.currentThread().getName().equals(originalThreadName)); + } + + public void doSomething(int i) { + System.out.println(Thread.currentThread().getName() + ": " + i); + assertTrue(!Thread.currentThread().getName().equals(originalThreadName)); + } + + public Future<String> returnSomething(int i) { + assertTrue(!Thread.currentThread().getName().equals(originalThreadName)); + return new AsyncResult<String>(Integer.toString(i)); + } + } + + + public static class AsyncMethodListener implements ApplicationListener { + + @Async + public void onApplicationEvent(ApplicationEvent event) { + listenerCalled++; + assertTrue(!Thread.currentThread().getName().equals(originalThreadName)); + } + } + + + @Async + public static class AsyncClassListener implements ApplicationListener { + + public AsyncClassListener() { + listenerConstructed++; + } + + public void onApplicationEvent(ApplicationEvent event) { + listenerCalled++; + assertTrue(!Thread.currentThread().getName().equals(originalThreadName)); + } + } + +} diff --git a/org.springframework.context/src/test/java/org/springframework/scripting/groovy/GroovyAspectIntegrationTests.java b/org.springframework.context/src/test/java/org/springframework/scripting/groovy/GroovyAspectIntegrationTests.java index 4bcc10e1a69..62f2d3223cc 100644 --- a/org.springframework.context/src/test/java/org/springframework/scripting/groovy/GroovyAspectIntegrationTests.java +++ b/org.springframework.context/src/test/java/org/springframework/scripting/groovy/GroovyAspectIntegrationTests.java @@ -1,100 +1,100 @@ -package org.springframework.scripting.groovy; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -import org.junit.After; -import org.junit.Test; -import org.springframework.context.support.GenericXmlApplicationContext; - -/** - * @author Dave Syer - */ -public class GroovyAspectIntegrationTests { - - private GenericXmlApplicationContext context; - - @After - public void close() { - if (context != null) { - context.close(); - } - } - - @Test - public void testJavaBean() { - - context = new GenericXmlApplicationContext(getClass(), getClass().getSimpleName()+"-java-context.xml"); - - TestService bean = context.getBean("javaBean", TestService.class); - LogUserAdvice logAdvice = context.getBean(LogUserAdvice.class); - - assertEquals(0, logAdvice.getCountThrows()); - try { - bean.sayHello(); - fail("Expected exception"); - } catch (RuntimeException e) { - assertEquals("TestServiceImpl", e.getMessage()); - } - assertEquals(1, logAdvice.getCountThrows()); - - } - - @Test - public void testGroovyBeanInterface() { - context = new GenericXmlApplicationContext(getClass(), getClass().getSimpleName()+"-groovy-interface-context.xml"); - - TestService bean = context.getBean("groovyBean", TestService.class); - LogUserAdvice logAdvice = context.getBean(LogUserAdvice.class); - - assertEquals(0, logAdvice.getCountThrows()); - try { - bean.sayHello(); - fail("Expected exception"); - } catch (RuntimeException e) { - assertEquals("GroovyServiceImpl", e.getMessage()); - } - assertEquals(1, logAdvice.getCountThrows()); - } - - - @Test - public void testGroovyBeanDynamic() { - - context = new GenericXmlApplicationContext(getClass(), getClass().getSimpleName()+"-groovy-dynamic-context.xml"); - - TestService bean = context.getBean("groovyBean", TestService.class); - LogUserAdvice logAdvice = context.getBean(LogUserAdvice.class); - - assertEquals(0, logAdvice.getCountThrows()); - try { - bean.sayHello(); - fail("Expected exception"); - } catch (RuntimeException e) { - assertEquals("GroovyServiceImpl", e.getMessage()); - } - // No proxy here because the pointcut only applies to the concrete class, not the interface - assertEquals(0, logAdvice.getCountThrows()); - assertEquals(0, logAdvice.getCountBefore()); - } - - @Test - public void testGroovyBeanProxyTargetClass() { - - context = new GenericXmlApplicationContext(getClass(), getClass().getSimpleName()+"-groovy-proxy-target-class-context.xml"); - - TestService bean = context.getBean("groovyBean", TestService.class); - LogUserAdvice logAdvice = context.getBean(LogUserAdvice.class); - - assertEquals(0, logAdvice.getCountThrows()); - try { - bean.sayHello(); - fail("Expected exception"); - } catch (TestException e) { - assertEquals("GroovyServiceImpl", e.getMessage()); - } - assertEquals(1, logAdvice.getCountBefore()); - assertEquals(1, logAdvice.getCountThrows()); - } - -} +package org.springframework.scripting.groovy; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import org.junit.After; +import org.junit.Test; +import org.springframework.context.support.GenericXmlApplicationContext; + +/** + * @author Dave Syer + */ +public class GroovyAspectIntegrationTests { + + private GenericXmlApplicationContext context; + + @After + public void close() { + if (context != null) { + context.close(); + } + } + + @Test + public void testJavaBean() { + + context = new GenericXmlApplicationContext(getClass(), getClass().getSimpleName()+"-java-context.xml"); + + TestService bean = context.getBean("javaBean", TestService.class); + LogUserAdvice logAdvice = context.getBean(LogUserAdvice.class); + + assertEquals(0, logAdvice.getCountThrows()); + try { + bean.sayHello(); + fail("Expected exception"); + } catch (RuntimeException e) { + assertEquals("TestServiceImpl", e.getMessage()); + } + assertEquals(1, logAdvice.getCountThrows()); + + } + + @Test + public void testGroovyBeanInterface() { + context = new GenericXmlApplicationContext(getClass(), getClass().getSimpleName()+"-groovy-interface-context.xml"); + + TestService bean = context.getBean("groovyBean", TestService.class); + LogUserAdvice logAdvice = context.getBean(LogUserAdvice.class); + + assertEquals(0, logAdvice.getCountThrows()); + try { + bean.sayHello(); + fail("Expected exception"); + } catch (RuntimeException e) { + assertEquals("GroovyServiceImpl", e.getMessage()); + } + assertEquals(1, logAdvice.getCountThrows()); + } + + + @Test + public void testGroovyBeanDynamic() { + + context = new GenericXmlApplicationContext(getClass(), getClass().getSimpleName()+"-groovy-dynamic-context.xml"); + + TestService bean = context.getBean("groovyBean", TestService.class); + LogUserAdvice logAdvice = context.getBean(LogUserAdvice.class); + + assertEquals(0, logAdvice.getCountThrows()); + try { + bean.sayHello(); + fail("Expected exception"); + } catch (RuntimeException e) { + assertEquals("GroovyServiceImpl", e.getMessage()); + } + // No proxy here because the pointcut only applies to the concrete class, not the interface + assertEquals(0, logAdvice.getCountThrows()); + assertEquals(0, logAdvice.getCountBefore()); + } + + @Test + public void testGroovyBeanProxyTargetClass() { + + context = new GenericXmlApplicationContext(getClass(), getClass().getSimpleName()+"-groovy-proxy-target-class-context.xml"); + + TestService bean = context.getBean("groovyBean", TestService.class); + LogUserAdvice logAdvice = context.getBean(LogUserAdvice.class); + + assertEquals(0, logAdvice.getCountThrows()); + try { + bean.sayHello(); + fail("Expected exception"); + } catch (TestException e) { + assertEquals("GroovyServiceImpl", e.getMessage()); + } + assertEquals(1, logAdvice.getCountBefore()); + assertEquals(1, logAdvice.getCountThrows()); + } + +} diff --git a/org.springframework.context/src/test/java/org/springframework/scripting/groovy/GroovyAspectTests.java b/org.springframework.context/src/test/java/org/springframework/scripting/groovy/GroovyAspectTests.java index 124842916bc..fa15ef7bfd2 100644 --- a/org.springframework.context/src/test/java/org/springframework/scripting/groovy/GroovyAspectTests.java +++ b/org.springframework.context/src/test/java/org/springframework/scripting/groovy/GroovyAspectTests.java @@ -1,101 +1,101 @@ -package org.springframework.scripting.groovy; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -import org.junit.Test; -import org.springframework.aop.Advisor; -import org.springframework.aop.aspectj.AspectJExpressionPointcut; -import org.springframework.aop.framework.ProxyFactory; -import org.springframework.aop.support.DefaultPointcutAdvisor; -import org.springframework.core.io.ClassPathResource; -import org.springframework.scripting.groovy.GroovyScriptFactory; -import org.springframework.scripting.support.ResourceScriptSource; -import org.springframework.util.ClassUtils; - -/** - * @author Dave Syer - */ -public class GroovyAspectTests { - - @Test - public void testManualGroovyBeanWithUnconditionalPointcut() throws Exception { - - LogUserAdvice logAdvice = new LogUserAdvice(); - - GroovyScriptFactory scriptFactory = new GroovyScriptFactory("GroovyServiceImpl.grv"); - TestService target = (TestService) scriptFactory.getScriptedObject(new ResourceScriptSource( - new ClassPathResource("GroovyServiceImpl.grv", getClass())), null); - - testAdvice(new DefaultPointcutAdvisor(logAdvice), logAdvice, target, "GroovyServiceImpl"); - - } - - @Test - public void testManualGroovyBeanWithStaticPointcut() throws Exception { - LogUserAdvice logAdvice = new LogUserAdvice(); - - GroovyScriptFactory scriptFactory = new GroovyScriptFactory("GroovyServiceImpl.grv"); - TestService target = (TestService) scriptFactory.getScriptedObject(new ResourceScriptSource( - new ClassPathResource("GroovyServiceImpl.grv", getClass())), null); - - AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); - pointcut.setExpression(String.format("execution(* %s.TestService+.*(..))", ClassUtils.getPackageName(getClass()))); - testAdvice(new DefaultPointcutAdvisor(pointcut, logAdvice), logAdvice, target, "GroovyServiceImpl", true); - } - - @Test - public void testManualGroovyBeanWithDynamicPointcut() throws Exception { - - LogUserAdvice logAdvice = new LogUserAdvice(); - - GroovyScriptFactory scriptFactory = new GroovyScriptFactory("GroovyServiceImpl.grv"); - TestService target = (TestService) scriptFactory.getScriptedObject(new ResourceScriptSource( - new ClassPathResource("GroovyServiceImpl.grv", getClass())), null); - - AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); - pointcut.setExpression(String.format("@within(%s.Log)", ClassUtils.getPackageName(getClass()))); - testAdvice(new DefaultPointcutAdvisor(pointcut, logAdvice), logAdvice, target, "GroovyServiceImpl", false); - - } - - @Test - public void testManualGroovyBeanWithDynamicPointcutProxyTargetClass() throws Exception { - - LogUserAdvice logAdvice = new LogUserAdvice(); - - GroovyScriptFactory scriptFactory = new GroovyScriptFactory("GroovyServiceImpl.grv"); - TestService target = (TestService) scriptFactory.getScriptedObject(new ResourceScriptSource( - new ClassPathResource("GroovyServiceImpl.grv", getClass())), null); - - AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); - pointcut.setExpression(String.format("@within(%s.Log)", ClassUtils.getPackageName(getClass()))); - testAdvice(new DefaultPointcutAdvisor(pointcut, logAdvice), logAdvice, target, "GroovyServiceImpl", true); - - } - - private void testAdvice(Advisor advisor, LogUserAdvice logAdvice, TestService target, String message) - throws Exception { - testAdvice(advisor, logAdvice, target, message, false); - } - - private void testAdvice(Advisor advisor, LogUserAdvice logAdvice, TestService target, String message, - boolean proxyTargetClass) throws Exception { - - logAdvice.reset(); - - ProxyFactory factory = new ProxyFactory(target); - factory.setProxyTargetClass(proxyTargetClass); - factory.addAdvisor(advisor); - TestService bean = (TestService) factory.getProxy(); - - assertEquals(0, logAdvice.getCountThrows()); - try { - bean.sayHello(); - fail("Expected exception"); - } catch (TestException e) { - assertEquals(message, e.getMessage()); - } - assertEquals(1, logAdvice.getCountThrows()); - } -} +package org.springframework.scripting.groovy; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import org.junit.Test; +import org.springframework.aop.Advisor; +import org.springframework.aop.aspectj.AspectJExpressionPointcut; +import org.springframework.aop.framework.ProxyFactory; +import org.springframework.aop.support.DefaultPointcutAdvisor; +import org.springframework.core.io.ClassPathResource; +import org.springframework.scripting.groovy.GroovyScriptFactory; +import org.springframework.scripting.support.ResourceScriptSource; +import org.springframework.util.ClassUtils; + +/** + * @author Dave Syer + */ +public class GroovyAspectTests { + + @Test + public void testManualGroovyBeanWithUnconditionalPointcut() throws Exception { + + LogUserAdvice logAdvice = new LogUserAdvice(); + + GroovyScriptFactory scriptFactory = new GroovyScriptFactory("GroovyServiceImpl.grv"); + TestService target = (TestService) scriptFactory.getScriptedObject(new ResourceScriptSource( + new ClassPathResource("GroovyServiceImpl.grv", getClass())), null); + + testAdvice(new DefaultPointcutAdvisor(logAdvice), logAdvice, target, "GroovyServiceImpl"); + + } + + @Test + public void testManualGroovyBeanWithStaticPointcut() throws Exception { + LogUserAdvice logAdvice = new LogUserAdvice(); + + GroovyScriptFactory scriptFactory = new GroovyScriptFactory("GroovyServiceImpl.grv"); + TestService target = (TestService) scriptFactory.getScriptedObject(new ResourceScriptSource( + new ClassPathResource("GroovyServiceImpl.grv", getClass())), null); + + AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); + pointcut.setExpression(String.format("execution(* %s.TestService+.*(..))", ClassUtils.getPackageName(getClass()))); + testAdvice(new DefaultPointcutAdvisor(pointcut, logAdvice), logAdvice, target, "GroovyServiceImpl", true); + } + + @Test + public void testManualGroovyBeanWithDynamicPointcut() throws Exception { + + LogUserAdvice logAdvice = new LogUserAdvice(); + + GroovyScriptFactory scriptFactory = new GroovyScriptFactory("GroovyServiceImpl.grv"); + TestService target = (TestService) scriptFactory.getScriptedObject(new ResourceScriptSource( + new ClassPathResource("GroovyServiceImpl.grv", getClass())), null); + + AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); + pointcut.setExpression(String.format("@within(%s.Log)", ClassUtils.getPackageName(getClass()))); + testAdvice(new DefaultPointcutAdvisor(pointcut, logAdvice), logAdvice, target, "GroovyServiceImpl", false); + + } + + @Test + public void testManualGroovyBeanWithDynamicPointcutProxyTargetClass() throws Exception { + + LogUserAdvice logAdvice = new LogUserAdvice(); + + GroovyScriptFactory scriptFactory = new GroovyScriptFactory("GroovyServiceImpl.grv"); + TestService target = (TestService) scriptFactory.getScriptedObject(new ResourceScriptSource( + new ClassPathResource("GroovyServiceImpl.grv", getClass())), null); + + AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); + pointcut.setExpression(String.format("@within(%s.Log)", ClassUtils.getPackageName(getClass()))); + testAdvice(new DefaultPointcutAdvisor(pointcut, logAdvice), logAdvice, target, "GroovyServiceImpl", true); + + } + + private void testAdvice(Advisor advisor, LogUserAdvice logAdvice, TestService target, String message) + throws Exception { + testAdvice(advisor, logAdvice, target, message, false); + } + + private void testAdvice(Advisor advisor, LogUserAdvice logAdvice, TestService target, String message, + boolean proxyTargetClass) throws Exception { + + logAdvice.reset(); + + ProxyFactory factory = new ProxyFactory(target); + factory.setProxyTargetClass(proxyTargetClass); + factory.addAdvisor(advisor); + TestService bean = (TestService) factory.getProxy(); + + assertEquals(0, logAdvice.getCountThrows()); + try { + bean.sayHello(); + fail("Expected exception"); + } catch (TestException e) { + assertEquals(message, e.getMessage()); + } + assertEquals(1, logAdvice.getCountThrows()); + } +} diff --git a/org.springframework.context/src/test/java/org/springframework/scripting/groovy/GroovyServiceImpl.grv b/org.springframework.context/src/test/java/org/springframework/scripting/groovy/GroovyServiceImpl.grv index ba7a1e15110..dadb2bc9503 100644 --- a/org.springframework.context/src/test/java/org/springframework/scripting/groovy/GroovyServiceImpl.grv +++ b/org.springframework.context/src/test/java/org/springframework/scripting/groovy/GroovyServiceImpl.grv @@ -1,11 +1,11 @@ -package org.springframework.scripting.groovy; - -@Log -public class GroovyServiceImpl implements TestService { - - public String sayHello() { - throw new TestException("GroovyServiceImpl"); - } - - +package org.springframework.scripting.groovy; + +@Log +public class GroovyServiceImpl implements TestService { + + public String sayHello() { + throw new TestException("GroovyServiceImpl"); + } + + } \ No newline at end of file diff --git a/org.springframework.context/src/test/java/org/springframework/scripting/groovy/Log.java b/org.springframework.context/src/test/java/org/springframework/scripting/groovy/Log.java index 2d23dfc682e..08b6b543c40 100644 --- a/org.springframework.context/src/test/java/org/springframework/scripting/groovy/Log.java +++ b/org.springframework.context/src/test/java/org/springframework/scripting/groovy/Log.java @@ -1,15 +1,15 @@ -package org.springframework.scripting.groovy; - -import java.lang.annotation.Inherited; -import java.lang.annotation.Target; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Documented; - -@Target({ ElementType.METHOD, ElementType.TYPE }) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Inherited -public @interface Log { -} +package org.springframework.scripting.groovy; + +import java.lang.annotation.Inherited; +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Documented; + +@Target({ ElementType.METHOD, ElementType.TYPE }) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Inherited +public @interface Log { +} diff --git a/org.springframework.context/src/test/java/org/springframework/scripting/groovy/LogUserAdvice.java b/org.springframework.context/src/test/java/org/springframework/scripting/groovy/LogUserAdvice.java index 2a553c504e2..53ade227752 100644 --- a/org.springframework.context/src/test/java/org/springframework/scripting/groovy/LogUserAdvice.java +++ b/org.springframework.context/src/test/java/org/springframework/scripting/groovy/LogUserAdvice.java @@ -1,41 +1,41 @@ -package org.springframework.scripting.groovy; - -import java.lang.reflect.Method; - -import org.springframework.aop.MethodBeforeAdvice; -import org.springframework.aop.ThrowsAdvice; - -public class LogUserAdvice implements MethodBeforeAdvice, ThrowsAdvice { - - private int countBefore = 0; - - private int countThrows = 0; - - public void before(Method method, Object[] objects, Object o) throws Throwable { - countBefore++; - System.out.println("Method:"+method.getName()); - } - - public void afterThrowing(Exception e) throws Throwable { - countThrows++; - System.out.println("***********************************************************************************"); - System.out.println("Exception caught:"); - System.out.println("***********************************************************************************"); - e.printStackTrace(); - throw e; - } - - public int getCountBefore() { - return countBefore; - } - - public int getCountThrows() { - return countThrows; - } - - public void reset() { - countThrows = 0; - countBefore = 0; - } - -} +package org.springframework.scripting.groovy; + +import java.lang.reflect.Method; + +import org.springframework.aop.MethodBeforeAdvice; +import org.springframework.aop.ThrowsAdvice; + +public class LogUserAdvice implements MethodBeforeAdvice, ThrowsAdvice { + + private int countBefore = 0; + + private int countThrows = 0; + + public void before(Method method, Object[] objects, Object o) throws Throwable { + countBefore++; + System.out.println("Method:"+method.getName()); + } + + public void afterThrowing(Exception e) throws Throwable { + countThrows++; + System.out.println("***********************************************************************************"); + System.out.println("Exception caught:"); + System.out.println("***********************************************************************************"); + e.printStackTrace(); + throw e; + } + + public int getCountBefore() { + return countBefore; + } + + public int getCountThrows() { + return countThrows; + } + + public void reset() { + countThrows = 0; + countBefore = 0; + } + +} diff --git a/org.springframework.context/src/test/java/org/springframework/scripting/groovy/TestService.java b/org.springframework.context/src/test/java/org/springframework/scripting/groovy/TestService.java index 33db91aaa79..5c123d11834 100644 --- a/org.springframework.context/src/test/java/org/springframework/scripting/groovy/TestService.java +++ b/org.springframework.context/src/test/java/org/springframework/scripting/groovy/TestService.java @@ -1,5 +1,5 @@ -package org.springframework.scripting.groovy; - -public interface TestService { - public String sayHello(); -} +package org.springframework.scripting.groovy; + +public interface TestService { + public String sayHello(); +} diff --git a/org.springframework.context/src/test/java/org/springframework/scripting/groovy/TestServiceImpl.java b/org.springframework.context/src/test/java/org/springframework/scripting/groovy/TestServiceImpl.java index f51a623836d..749fc42fdef 100644 --- a/org.springframework.context/src/test/java/org/springframework/scripting/groovy/TestServiceImpl.java +++ b/org.springframework.context/src/test/java/org/springframework/scripting/groovy/TestServiceImpl.java @@ -1,8 +1,8 @@ -package org.springframework.scripting.groovy; - -@Log -public class TestServiceImpl implements TestService{ - public String sayHello() { - throw new TestException("TestServiceImpl"); - } -} +package org.springframework.scripting.groovy; + +@Log +public class TestServiceImpl implements TestService{ + public String sayHello() { + throw new TestException("TestServiceImpl"); + } +} diff --git a/org.springframework.context/src/test/java/org/springframework/validation/beanvalidation/BeanValidationPostProcessorTests.java b/org.springframework.context/src/test/java/org/springframework/validation/beanvalidation/BeanValidationPostProcessorTests.java index 42ca119e736..b98fb420072 100644 --- a/org.springframework.context/src/test/java/org/springframework/validation/beanvalidation/BeanValidationPostProcessorTests.java +++ b/org.springframework.context/src/test/java/org/springframework/validation/beanvalidation/BeanValidationPostProcessorTests.java @@ -1,156 +1,156 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.validation.beanvalidation; - -import javax.annotation.PostConstruct; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; - -import static org.junit.Assert.*; -import org.junit.Test; - -import org.springframework.beans.TestBean; -import org.springframework.beans.factory.BeanCreationException; -import org.springframework.beans.factory.support.RootBeanDefinition; -import org.springframework.context.annotation.CommonAnnotationBeanPostProcessor; -import org.springframework.context.support.GenericApplicationContext; - -/** - * @author Juergen Hoeller - * @since 3.0 - */ -public class BeanValidationPostProcessorTests { - - @Test - public void testNotNullConstraint() { - GenericApplicationContext ac = new GenericApplicationContext(); - ac.registerBeanDefinition("bvpp", new RootBeanDefinition(BeanValidationPostProcessor.class)); - ac.registerBeanDefinition("capp", new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class)); - ac.registerBeanDefinition("bean", new RootBeanDefinition(NotNullConstrainedBean.class)); - try { - ac.refresh(); - fail("Should have thrown BeanCreationException"); - } - catch (BeanCreationException ex) { - assertTrue(ex.getRootCause().getMessage().contains("testBean")); - assertTrue(ex.getRootCause().getMessage().contains("invalid")); - } - } - - @Test - public void testNotNullConstraintSatisfied() { - GenericApplicationContext ac = new GenericApplicationContext(); - ac.registerBeanDefinition("bvpp", new RootBeanDefinition(BeanValidationPostProcessor.class)); - ac.registerBeanDefinition("capp", new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class)); - RootBeanDefinition bd = new RootBeanDefinition(NotNullConstrainedBean.class); - bd.getPropertyValues().add("testBean", new TestBean()); - ac.registerBeanDefinition("bean", bd); - ac.refresh(); - } - - @Test - public void testNotNullConstraintAfterInitialization() { - GenericApplicationContext ac = new GenericApplicationContext(); - RootBeanDefinition bvpp = new RootBeanDefinition(BeanValidationPostProcessor.class); - bvpp.getPropertyValues().add("afterInitialization", true); - ac.registerBeanDefinition("bvpp", bvpp); - ac.registerBeanDefinition("capp", new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class)); - ac.registerBeanDefinition("bean", new RootBeanDefinition(AfterInitConstraintBean.class)); - ac.refresh(); - } - - @Test - public void testSizeConstraint() { - GenericApplicationContext ac = new GenericApplicationContext(); - ac.registerBeanDefinition("bvpp", new RootBeanDefinition(BeanValidationPostProcessor.class)); - RootBeanDefinition bd = new RootBeanDefinition(NotNullConstrainedBean.class); - bd.getPropertyValues().add("testBean", new TestBean()); - bd.getPropertyValues().add("stringValue", "s"); - ac.registerBeanDefinition("bean", bd); - try { - ac.refresh(); - fail("Should have thrown BeanCreationException"); - } - catch (BeanCreationException ex) { - assertTrue(ex.getRootCause().getMessage().contains("stringValue")); - assertTrue(ex.getRootCause().getMessage().contains("invalid")); - } - } - - @Test - public void testSizeConstraintSatisfied() { - GenericApplicationContext ac = new GenericApplicationContext(); - ac.registerBeanDefinition("bvpp", new RootBeanDefinition(BeanValidationPostProcessor.class)); - RootBeanDefinition bd = new RootBeanDefinition(NotNullConstrainedBean.class); - bd.getPropertyValues().add("testBean", new TestBean()); - bd.getPropertyValues().add("stringValue", "ss"); - ac.registerBeanDefinition("bean", bd); - ac.refresh(); - } - - - public static class NotNullConstrainedBean { - - @NotNull - private TestBean testBean; - - @Size(min = 2) - private String stringValue; - - public TestBean getTestBean() { - return testBean; - } - - public void setTestBean(TestBean testBean) { - this.testBean = testBean; - } - - public String getStringValue() { - return stringValue; - } - - public void setStringValue(String stringValue) { - this.stringValue = stringValue; - } - - @PostConstruct - public void init() { - assertNotNull("Shouldn't be here after constraint checking", this.testBean); - } - } - - - public static class AfterInitConstraintBean { - - @NotNull - private TestBean testBean; - - public TestBean getTestBean() { - return testBean; - } - - public void setTestBean(TestBean testBean) { - this.testBean = testBean; - } - - @PostConstruct - public void init() { - this.testBean = new TestBean(); - } - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.validation.beanvalidation; + +import javax.annotation.PostConstruct; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +import static org.junit.Assert.*; +import org.junit.Test; + +import org.springframework.beans.TestBean; +import org.springframework.beans.factory.BeanCreationException; +import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.context.annotation.CommonAnnotationBeanPostProcessor; +import org.springframework.context.support.GenericApplicationContext; + +/** + * @author Juergen Hoeller + * @since 3.0 + */ +public class BeanValidationPostProcessorTests { + + @Test + public void testNotNullConstraint() { + GenericApplicationContext ac = new GenericApplicationContext(); + ac.registerBeanDefinition("bvpp", new RootBeanDefinition(BeanValidationPostProcessor.class)); + ac.registerBeanDefinition("capp", new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class)); + ac.registerBeanDefinition("bean", new RootBeanDefinition(NotNullConstrainedBean.class)); + try { + ac.refresh(); + fail("Should have thrown BeanCreationException"); + } + catch (BeanCreationException ex) { + assertTrue(ex.getRootCause().getMessage().contains("testBean")); + assertTrue(ex.getRootCause().getMessage().contains("invalid")); + } + } + + @Test + public void testNotNullConstraintSatisfied() { + GenericApplicationContext ac = new GenericApplicationContext(); + ac.registerBeanDefinition("bvpp", new RootBeanDefinition(BeanValidationPostProcessor.class)); + ac.registerBeanDefinition("capp", new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class)); + RootBeanDefinition bd = new RootBeanDefinition(NotNullConstrainedBean.class); + bd.getPropertyValues().add("testBean", new TestBean()); + ac.registerBeanDefinition("bean", bd); + ac.refresh(); + } + + @Test + public void testNotNullConstraintAfterInitialization() { + GenericApplicationContext ac = new GenericApplicationContext(); + RootBeanDefinition bvpp = new RootBeanDefinition(BeanValidationPostProcessor.class); + bvpp.getPropertyValues().add("afterInitialization", true); + ac.registerBeanDefinition("bvpp", bvpp); + ac.registerBeanDefinition("capp", new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class)); + ac.registerBeanDefinition("bean", new RootBeanDefinition(AfterInitConstraintBean.class)); + ac.refresh(); + } + + @Test + public void testSizeConstraint() { + GenericApplicationContext ac = new GenericApplicationContext(); + ac.registerBeanDefinition("bvpp", new RootBeanDefinition(BeanValidationPostProcessor.class)); + RootBeanDefinition bd = new RootBeanDefinition(NotNullConstrainedBean.class); + bd.getPropertyValues().add("testBean", new TestBean()); + bd.getPropertyValues().add("stringValue", "s"); + ac.registerBeanDefinition("bean", bd); + try { + ac.refresh(); + fail("Should have thrown BeanCreationException"); + } + catch (BeanCreationException ex) { + assertTrue(ex.getRootCause().getMessage().contains("stringValue")); + assertTrue(ex.getRootCause().getMessage().contains("invalid")); + } + } + + @Test + public void testSizeConstraintSatisfied() { + GenericApplicationContext ac = new GenericApplicationContext(); + ac.registerBeanDefinition("bvpp", new RootBeanDefinition(BeanValidationPostProcessor.class)); + RootBeanDefinition bd = new RootBeanDefinition(NotNullConstrainedBean.class); + bd.getPropertyValues().add("testBean", new TestBean()); + bd.getPropertyValues().add("stringValue", "ss"); + ac.registerBeanDefinition("bean", bd); + ac.refresh(); + } + + + public static class NotNullConstrainedBean { + + @NotNull + private TestBean testBean; + + @Size(min = 2) + private String stringValue; + + public TestBean getTestBean() { + return testBean; + } + + public void setTestBean(TestBean testBean) { + this.testBean = testBean; + } + + public String getStringValue() { + return stringValue; + } + + public void setStringValue(String stringValue) { + this.stringValue = stringValue; + } + + @PostConstruct + public void init() { + assertNotNull("Shouldn't be here after constraint checking", this.testBean); + } + } + + + public static class AfterInitConstraintBean { + + @NotNull + private TestBean testBean; + + public TestBean getTestBean() { + return testBean; + } + + public void setTestBean(TestBean testBean) { + this.testBean = testBean; + } + + @PostConstruct + public void init() { + this.testBean = new TestBean(); + } + } + +} diff --git a/org.springframework.context/src/test/java/org/springframework/validation/beanvalidation/ValidatorFactoryTests.java b/org.springframework.context/src/test/java/org/springframework/validation/beanvalidation/ValidatorFactoryTests.java index c6fc15faf75..4e69535108d 100644 --- a/org.springframework.context/src/test/java/org/springframework/validation/beanvalidation/ValidatorFactoryTests.java +++ b/org.springframework.context/src/test/java/org/springframework/validation/beanvalidation/ValidatorFactoryTests.java @@ -1,270 +1,270 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.validation.beanvalidation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.util.Arrays; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; -import javax.validation.Constraint; -import javax.validation.ConstraintValidator; -import javax.validation.ConstraintValidatorContext; -import javax.validation.ConstraintViolation; -import javax.validation.Valid; -import javax.validation.constraints.NotNull; - -import org.hibernate.validator.HibernateValidator; -import org.junit.Test; - -import org.springframework.validation.BeanPropertyBindingResult; -import org.springframework.validation.FieldError; -import org.springframework.validation.ObjectError; - -import static org.junit.Assert.*; - -/** - * @author Juergen Hoeller - * @since 3.0 - */ -public class ValidatorFactoryTests { - - @Test - public void testSimpleValidation() throws Exception { - LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); - validator.afterPropertiesSet(); - ValidPerson person = new ValidPerson(); - Set<ConstraintViolation<ValidPerson>> result = validator.validate(person); - assertEquals(2, result.size()); - for (ConstraintViolation<ValidPerson> cv : result) { - String path = cv.getPropertyPath().toString(); - if ("name".equals(path) || "address.street".equals(path)) { - assertTrue(cv.getConstraintDescriptor().getAnnotation() instanceof NotNull); - } - else { - fail("Invalid constraint violation with path '" + path + "'"); - } - } - } - - @Test - public void testSimpleValidationWithCustomProvider() throws Exception { - LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); - validator.setProviderClass(HibernateValidator.class); - validator.afterPropertiesSet(); - ValidPerson person = new ValidPerson(); - Set<ConstraintViolation<ValidPerson>> result = validator.validate(person); - assertEquals(2, result.size()); - for (ConstraintViolation<ValidPerson> cv : result) { - String path = cv.getPropertyPath().toString(); - if ("name".equals(path) || "address.street".equals(path)) { - assertTrue(cv.getConstraintDescriptor().getAnnotation() instanceof NotNull); - } - else { - fail("Invalid constraint violation with path '" + path + "'"); - } - } - } - - @Test - public void testSimpleValidationWithClassLevel() throws Exception { - LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); - validator.afterPropertiesSet(); - ValidPerson person = new ValidPerson(); - person.setName("Juergen"); - person.getAddress().setStreet("Juergen's Street"); - Set<ConstraintViolation<ValidPerson>> result = validator.validate(person); - assertEquals(1, result.size()); - Iterator<ConstraintViolation<ValidPerson>> iterator = result.iterator(); - ConstraintViolation cv = iterator.next(); - assertEquals("", cv.getPropertyPath().toString()); - assertTrue(cv.getConstraintDescriptor().getAnnotation() instanceof NameAddressValid); - } - - @Test - public void testSpringValidation() throws Exception { - LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); - validator.afterPropertiesSet(); - ValidPerson person = new ValidPerson(); - BeanPropertyBindingResult result = new BeanPropertyBindingResult(person, "person"); - validator.validate(person, result); - assertEquals(2, result.getErrorCount()); - FieldError fieldError = result.getFieldError("name"); - assertEquals("name", fieldError.getField()); - System.out.println(Arrays.asList(fieldError.getCodes())); - System.out.println(fieldError.getDefaultMessage()); - fieldError = result.getFieldError("address.street"); - assertEquals("address.street", fieldError.getField()); - System.out.println(Arrays.asList(fieldError.getCodes())); - System.out.println(fieldError.getDefaultMessage()); - } - - @Test - public void testSpringValidationWithClassLevel() throws Exception { - LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); - validator.afterPropertiesSet(); - ValidPerson person = new ValidPerson(); - person.setName("Juergen"); - person.getAddress().setStreet("Juergen's Street"); - BeanPropertyBindingResult result = new BeanPropertyBindingResult(person, "person"); - validator.validate(person, result); - assertEquals(1, result.getErrorCount()); - ObjectError globalError = result.getGlobalError(); - System.out.println(Arrays.asList(globalError.getCodes())); - System.out.println(globalError.getDefaultMessage()); - } - - @Test - public void testSpringValidationWithErrorInListElement() throws Exception { - LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); - validator.afterPropertiesSet(); - ValidPerson person = new ValidPerson(); - person.getAddressList().add(new ValidAddress()); - BeanPropertyBindingResult result = new BeanPropertyBindingResult(person, "person"); - validator.validate(person, result); - assertEquals(3, result.getErrorCount()); - FieldError fieldError = result.getFieldError("name"); - assertEquals("name", fieldError.getField()); - System.out.println(Arrays.asList(fieldError.getCodes())); - System.out.println(fieldError.getDefaultMessage()); - fieldError = result.getFieldError("address.street"); - assertEquals("address.street", fieldError.getField()); - System.out.println(Arrays.asList(fieldError.getCodes())); - System.out.println(fieldError.getDefaultMessage()); - fieldError = result.getFieldError("addressList[0].street"); - assertEquals("addressList[0].street", fieldError.getField()); - System.out.println(Arrays.asList(fieldError.getCodes())); - System.out.println(fieldError.getDefaultMessage()); - } - - @Test - public void testSpringValidationWithErrorInSetElement() throws Exception { - LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); - validator.afterPropertiesSet(); - ValidPerson person = new ValidPerson(); - person.getAddressSet().add(new ValidAddress()); - BeanPropertyBindingResult result = new BeanPropertyBindingResult(person, "person"); - validator.validate(person, result); - assertEquals(3, result.getErrorCount()); - FieldError fieldError = result.getFieldError("name"); - assertEquals("name", fieldError.getField()); - System.out.println(Arrays.asList(fieldError.getCodes())); - System.out.println(fieldError.getDefaultMessage()); - fieldError = result.getFieldError("address.street"); - assertEquals("address.street", fieldError.getField()); - System.out.println(Arrays.asList(fieldError.getCodes())); - System.out.println(fieldError.getDefaultMessage()); - fieldError = result.getFieldError("addressSet[].street"); - assertEquals("addressSet[].street", fieldError.getField()); - System.out.println(Arrays.asList(fieldError.getCodes())); - System.out.println(fieldError.getDefaultMessage()); - } - - - @NameAddressValid - public static class ValidPerson { - - @NotNull - private String name; - - @Valid - private ValidAddress address = new ValidAddress(); - - @Valid - private List<ValidAddress> addressList = new LinkedList<ValidAddress>(); - - @Valid - private Set<ValidAddress> addressSet = new LinkedHashSet<ValidAddress>(); - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public ValidAddress getAddress() { - return address; - } - - public void setAddress(ValidAddress address) { - this.address = address; - } - - public List<ValidAddress> getAddressList() { - return addressList; - } - - public void setAddressList(List<ValidAddress> addressList) { - this.addressList = addressList; - } - - public Set<ValidAddress> getAddressSet() { - return addressSet; - } - - public void setAddressSet(Set<ValidAddress> addressSet) { - this.addressSet = addressSet; - } - } - - - public static class ValidAddress { - - @NotNull - private String street; - - public String getStreet() { - return street; - } - - public void setStreet(String street) { - this.street = street; - } - } - - - @Target(ElementType.TYPE) - @Retention(RetentionPolicy.RUNTIME) - @Constraint(validatedBy = NameAddressValidator.class) - public @interface NameAddressValid { - - String message() default "Street must not contain name"; - - Class<?>[] groups() default {}; - - Class<?>[] payload() default {}; - } - - - public static class NameAddressValidator implements ConstraintValidator<NameAddressValid, ValidPerson> { - - public void initialize(NameAddressValid constraintAnnotation) { - } - - public boolean isValid(ValidPerson value, ConstraintValidatorContext constraintValidatorContext) { - return (value.name == null || !value.address.street.contains(value.name)); - } - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.validation.beanvalidation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.util.Arrays; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import javax.validation.Constraint; +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; +import javax.validation.ConstraintViolation; +import javax.validation.Valid; +import javax.validation.constraints.NotNull; + +import org.hibernate.validator.HibernateValidator; +import org.junit.Test; + +import org.springframework.validation.BeanPropertyBindingResult; +import org.springframework.validation.FieldError; +import org.springframework.validation.ObjectError; + +import static org.junit.Assert.*; + +/** + * @author Juergen Hoeller + * @since 3.0 + */ +public class ValidatorFactoryTests { + + @Test + public void testSimpleValidation() throws Exception { + LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); + validator.afterPropertiesSet(); + ValidPerson person = new ValidPerson(); + Set<ConstraintViolation<ValidPerson>> result = validator.validate(person); + assertEquals(2, result.size()); + for (ConstraintViolation<ValidPerson> cv : result) { + String path = cv.getPropertyPath().toString(); + if ("name".equals(path) || "address.street".equals(path)) { + assertTrue(cv.getConstraintDescriptor().getAnnotation() instanceof NotNull); + } + else { + fail("Invalid constraint violation with path '" + path + "'"); + } + } + } + + @Test + public void testSimpleValidationWithCustomProvider() throws Exception { + LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); + validator.setProviderClass(HibernateValidator.class); + validator.afterPropertiesSet(); + ValidPerson person = new ValidPerson(); + Set<ConstraintViolation<ValidPerson>> result = validator.validate(person); + assertEquals(2, result.size()); + for (ConstraintViolation<ValidPerson> cv : result) { + String path = cv.getPropertyPath().toString(); + if ("name".equals(path) || "address.street".equals(path)) { + assertTrue(cv.getConstraintDescriptor().getAnnotation() instanceof NotNull); + } + else { + fail("Invalid constraint violation with path '" + path + "'"); + } + } + } + + @Test + public void testSimpleValidationWithClassLevel() throws Exception { + LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); + validator.afterPropertiesSet(); + ValidPerson person = new ValidPerson(); + person.setName("Juergen"); + person.getAddress().setStreet("Juergen's Street"); + Set<ConstraintViolation<ValidPerson>> result = validator.validate(person); + assertEquals(1, result.size()); + Iterator<ConstraintViolation<ValidPerson>> iterator = result.iterator(); + ConstraintViolation cv = iterator.next(); + assertEquals("", cv.getPropertyPath().toString()); + assertTrue(cv.getConstraintDescriptor().getAnnotation() instanceof NameAddressValid); + } + + @Test + public void testSpringValidation() throws Exception { + LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); + validator.afterPropertiesSet(); + ValidPerson person = new ValidPerson(); + BeanPropertyBindingResult result = new BeanPropertyBindingResult(person, "person"); + validator.validate(person, result); + assertEquals(2, result.getErrorCount()); + FieldError fieldError = result.getFieldError("name"); + assertEquals("name", fieldError.getField()); + System.out.println(Arrays.asList(fieldError.getCodes())); + System.out.println(fieldError.getDefaultMessage()); + fieldError = result.getFieldError("address.street"); + assertEquals("address.street", fieldError.getField()); + System.out.println(Arrays.asList(fieldError.getCodes())); + System.out.println(fieldError.getDefaultMessage()); + } + + @Test + public void testSpringValidationWithClassLevel() throws Exception { + LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); + validator.afterPropertiesSet(); + ValidPerson person = new ValidPerson(); + person.setName("Juergen"); + person.getAddress().setStreet("Juergen's Street"); + BeanPropertyBindingResult result = new BeanPropertyBindingResult(person, "person"); + validator.validate(person, result); + assertEquals(1, result.getErrorCount()); + ObjectError globalError = result.getGlobalError(); + System.out.println(Arrays.asList(globalError.getCodes())); + System.out.println(globalError.getDefaultMessage()); + } + + @Test + public void testSpringValidationWithErrorInListElement() throws Exception { + LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); + validator.afterPropertiesSet(); + ValidPerson person = new ValidPerson(); + person.getAddressList().add(new ValidAddress()); + BeanPropertyBindingResult result = new BeanPropertyBindingResult(person, "person"); + validator.validate(person, result); + assertEquals(3, result.getErrorCount()); + FieldError fieldError = result.getFieldError("name"); + assertEquals("name", fieldError.getField()); + System.out.println(Arrays.asList(fieldError.getCodes())); + System.out.println(fieldError.getDefaultMessage()); + fieldError = result.getFieldError("address.street"); + assertEquals("address.street", fieldError.getField()); + System.out.println(Arrays.asList(fieldError.getCodes())); + System.out.println(fieldError.getDefaultMessage()); + fieldError = result.getFieldError("addressList[0].street"); + assertEquals("addressList[0].street", fieldError.getField()); + System.out.println(Arrays.asList(fieldError.getCodes())); + System.out.println(fieldError.getDefaultMessage()); + } + + @Test + public void testSpringValidationWithErrorInSetElement() throws Exception { + LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); + validator.afterPropertiesSet(); + ValidPerson person = new ValidPerson(); + person.getAddressSet().add(new ValidAddress()); + BeanPropertyBindingResult result = new BeanPropertyBindingResult(person, "person"); + validator.validate(person, result); + assertEquals(3, result.getErrorCount()); + FieldError fieldError = result.getFieldError("name"); + assertEquals("name", fieldError.getField()); + System.out.println(Arrays.asList(fieldError.getCodes())); + System.out.println(fieldError.getDefaultMessage()); + fieldError = result.getFieldError("address.street"); + assertEquals("address.street", fieldError.getField()); + System.out.println(Arrays.asList(fieldError.getCodes())); + System.out.println(fieldError.getDefaultMessage()); + fieldError = result.getFieldError("addressSet[].street"); + assertEquals("addressSet[].street", fieldError.getField()); + System.out.println(Arrays.asList(fieldError.getCodes())); + System.out.println(fieldError.getDefaultMessage()); + } + + + @NameAddressValid + public static class ValidPerson { + + @NotNull + private String name; + + @Valid + private ValidAddress address = new ValidAddress(); + + @Valid + private List<ValidAddress> addressList = new LinkedList<ValidAddress>(); + + @Valid + private Set<ValidAddress> addressSet = new LinkedHashSet<ValidAddress>(); + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public ValidAddress getAddress() { + return address; + } + + public void setAddress(ValidAddress address) { + this.address = address; + } + + public List<ValidAddress> getAddressList() { + return addressList; + } + + public void setAddressList(List<ValidAddress> addressList) { + this.addressList = addressList; + } + + public Set<ValidAddress> getAddressSet() { + return addressSet; + } + + public void setAddressSet(Set<ValidAddress> addressSet) { + this.addressSet = addressSet; + } + } + + + public static class ValidAddress { + + @NotNull + private String street; + + public String getStreet() { + return street; + } + + public void setStreet(String street) { + this.street = street; + } + } + + + @Target(ElementType.TYPE) + @Retention(RetentionPolicy.RUNTIME) + @Constraint(validatedBy = NameAddressValidator.class) + public @interface NameAddressValid { + + String message() default "Street must not contain name"; + + Class<?>[] groups() default {}; + + Class<?>[] payload() default {}; + } + + + public static class NameAddressValidator implements ConstraintValidator<NameAddressValid, ValidPerson> { + + public void initialize(NameAddressValid constraintAnnotation) { + } + + public boolean isValid(ValidPerson value, ConstraintValidatorContext constraintValidatorContext) { + return (value.name == null || !value.address.street.contains(value.name)); + } + } + +} diff --git a/org.springframework.core/src/main/java/org/springframework/core/ExceptionDepthComparator.java b/org.springframework.core/src/main/java/org/springframework/core/ExceptionDepthComparator.java index c856b86a03f..53e3425f369 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/ExceptionDepthComparator.java +++ b/org.springframework.core/src/main/java/org/springframework/core/ExceptionDepthComparator.java @@ -1,96 +1,96 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.core; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -import org.springframework.util.Assert; - -/** - * Comparator capable of sorting exceptions based on their depth from the thrown exception type. - * - * @author Juergen Hoeller - * @author Arjen Poutsma - * @since 3.0.3 - */ -public class ExceptionDepthComparator implements Comparator<Class<? extends Throwable>> { - - private final Class<? extends Throwable> targetException; - - - /** - * Create a new ExceptionDepthComparator for the given exception. - * @param exception the target exception to compare to when sorting by depth - */ - public ExceptionDepthComparator(Throwable exception) { - Assert.notNull(exception, "Target exception must not be null"); - this.targetException = exception.getClass(); - } - - /** - * Create a new ExceptionDepthComparator for the given exception type. - * @param exceptionType the target exception type to compare to when sorting by depth - */ - public ExceptionDepthComparator(Class<? extends Throwable> exceptionType) { - Assert.notNull(exceptionType, "Target exception type must not be null"); - this.targetException = exceptionType; - } - - - public int compare(Class<? extends Throwable> o1, Class<? extends Throwable> o2) { - int depth1 = getDepth(o1, this.targetException, 0); - int depth2 = getDepth(o2, this.targetException, 0); - return (depth1 - depth2); - } - - private int getDepth(Class declaredException, Class exceptionToMatch, int depth) { - if (declaredException.equals(exceptionToMatch)) { - // Found it! - return depth; - } - // If we've gone as far as we can go and haven't found it... - if (Throwable.class.equals(exceptionToMatch)) { - return Integer.MAX_VALUE; - } - return getDepth(declaredException, exceptionToMatch.getSuperclass(), depth + 1); - } - - - /** - * Obtain the closest match from the given exception types for the given target exception. - * @param exceptionTypes the collection of exception types - * @param targetException the target exception to find a match for - * @return the closest matching exception type from the given collection - */ - public static Class<? extends Throwable> findClosestMatch( - Collection<Class<? extends Throwable>> exceptionTypes, Throwable targetException) { - - Assert.notEmpty(exceptionTypes, "Exception types must not be empty"); - if (exceptionTypes.size() == 1) { - return exceptionTypes.iterator().next(); - } - List<Class<? extends Throwable>> handledExceptions = - new ArrayList<Class<? extends Throwable>>(exceptionTypes); - Collections.sort(handledExceptions, new ExceptionDepthComparator(targetException)); - return handledExceptions.get(0); - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.core; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import org.springframework.util.Assert; + +/** + * Comparator capable of sorting exceptions based on their depth from the thrown exception type. + * + * @author Juergen Hoeller + * @author Arjen Poutsma + * @since 3.0.3 + */ +public class ExceptionDepthComparator implements Comparator<Class<? extends Throwable>> { + + private final Class<? extends Throwable> targetException; + + + /** + * Create a new ExceptionDepthComparator for the given exception. + * @param exception the target exception to compare to when sorting by depth + */ + public ExceptionDepthComparator(Throwable exception) { + Assert.notNull(exception, "Target exception must not be null"); + this.targetException = exception.getClass(); + } + + /** + * Create a new ExceptionDepthComparator for the given exception type. + * @param exceptionType the target exception type to compare to when sorting by depth + */ + public ExceptionDepthComparator(Class<? extends Throwable> exceptionType) { + Assert.notNull(exceptionType, "Target exception type must not be null"); + this.targetException = exceptionType; + } + + + public int compare(Class<? extends Throwable> o1, Class<? extends Throwable> o2) { + int depth1 = getDepth(o1, this.targetException, 0); + int depth2 = getDepth(o2, this.targetException, 0); + return (depth1 - depth2); + } + + private int getDepth(Class declaredException, Class exceptionToMatch, int depth) { + if (declaredException.equals(exceptionToMatch)) { + // Found it! + return depth; + } + // If we've gone as far as we can go and haven't found it... + if (Throwable.class.equals(exceptionToMatch)) { + return Integer.MAX_VALUE; + } + return getDepth(declaredException, exceptionToMatch.getSuperclass(), depth + 1); + } + + + /** + * Obtain the closest match from the given exception types for the given target exception. + * @param exceptionTypes the collection of exception types + * @param targetException the target exception to find a match for + * @return the closest matching exception type from the given collection + */ + public static Class<? extends Throwable> findClosestMatch( + Collection<Class<? extends Throwable>> exceptionTypes, Throwable targetException) { + + Assert.notEmpty(exceptionTypes, "Exception types must not be empty"); + if (exceptionTypes.size() == 1) { + return exceptionTypes.iterator().next(); + } + List<Class<? extends Throwable>> handledExceptions = + new ArrayList<Class<? extends Throwable>>(exceptionTypes); + Collections.sort(handledExceptions, new ExceptionDepthComparator(targetException)); + return handledExceptions.get(0); + } + +} diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/support/ConvertingPropertyEditorAdapter.java b/org.springframework.core/src/main/java/org/springframework/core/convert/support/ConvertingPropertyEditorAdapter.java index 777861061cd..47cadd667da 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/support/ConvertingPropertyEditorAdapter.java +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/support/ConvertingPropertyEditorAdapter.java @@ -1,72 +1,72 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.core.convert.support; - -import java.beans.PropertyEditorSupport; - -import org.springframework.core.convert.ConversionService; -import org.springframework.core.convert.TypeDescriptor; -import org.springframework.util.Assert; - -/** - * Adapter that exposes a {@link java.beans.PropertyEditor} for any given - * {@link org.springframework.core.convert.ConversionService} and specific target type. - * - * @author Juergen Hoeller - * @since 3.0 - */ -public class ConvertingPropertyEditorAdapter extends PropertyEditorSupport { - - private final ConversionService conversionService; - - private final TypeDescriptor targetDescriptor; - - private final boolean canConvertToString; - - - /** - * Create a new ConvertingPropertyEditorAdapter for a given - * {@link org.springframework.core.convert.ConversionService} - * and the given target type. - * @param conversionService the ConversionService to delegate to - * @param targetDescriptor the target type to convert to - */ - public ConvertingPropertyEditorAdapter(ConversionService conversionService, TypeDescriptor targetDescriptor) { - Assert.notNull(conversionService, "ConversionService must not be null"); - Assert.notNull(targetDescriptor, "TypeDescriptor must not be null"); - this.conversionService = conversionService; - this.targetDescriptor = targetDescriptor; - this.canConvertToString = conversionService.canConvert(this.targetDescriptor, TypeDescriptor.valueOf(String.class)); - } - - - @Override - public void setAsText(String text) throws IllegalArgumentException { - setValue(this.conversionService.convert(text, TypeDescriptor.valueOf(String.class), this.targetDescriptor)); - } - - @Override - public String getAsText() { - if (this.canConvertToString) { - return (String) this.conversionService.convert(getValue(), this.targetDescriptor, TypeDescriptor.valueOf(String.class)); - } - else { - return null; - } - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.core.convert.support; + +import java.beans.PropertyEditorSupport; + +import org.springframework.core.convert.ConversionService; +import org.springframework.core.convert.TypeDescriptor; +import org.springframework.util.Assert; + +/** + * Adapter that exposes a {@link java.beans.PropertyEditor} for any given + * {@link org.springframework.core.convert.ConversionService} and specific target type. + * + * @author Juergen Hoeller + * @since 3.0 + */ +public class ConvertingPropertyEditorAdapter extends PropertyEditorSupport { + + private final ConversionService conversionService; + + private final TypeDescriptor targetDescriptor; + + private final boolean canConvertToString; + + + /** + * Create a new ConvertingPropertyEditorAdapter for a given + * {@link org.springframework.core.convert.ConversionService} + * and the given target type. + * @param conversionService the ConversionService to delegate to + * @param targetDescriptor the target type to convert to + */ + public ConvertingPropertyEditorAdapter(ConversionService conversionService, TypeDescriptor targetDescriptor) { + Assert.notNull(conversionService, "ConversionService must not be null"); + Assert.notNull(targetDescriptor, "TypeDescriptor must not be null"); + this.conversionService = conversionService; + this.targetDescriptor = targetDescriptor; + this.canConvertToString = conversionService.canConvert(this.targetDescriptor, TypeDescriptor.valueOf(String.class)); + } + + + @Override + public void setAsText(String text) throws IllegalArgumentException { + setValue(this.conversionService.convert(text, TypeDescriptor.valueOf(String.class), this.targetDescriptor)); + } + + @Override + public String getAsText() { + if (this.canConvertToString) { + return (String) this.conversionService.convert(getValue(), this.targetDescriptor, TypeDescriptor.valueOf(String.class)); + } + else { + return null; + } + } + +} diff --git a/org.springframework.core/src/main/java/org/springframework/core/io/AbstractFileResolvingResource.java b/org.springframework.core/src/main/java/org/springframework/core/io/AbstractFileResolvingResource.java index fd00f909f0c..f5c5f18034a 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/io/AbstractFileResolvingResource.java +++ b/org.springframework.core/src/main/java/org/springframework/core/io/AbstractFileResolvingResource.java @@ -1,201 +1,201 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.core.io; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.URI; -import java.net.URL; -import java.net.URLConnection; - -import org.springframework.util.ResourceUtils; - -/** - * Abstract base class for resources which resolve URLs into File references, - * such as {@link UrlResource} or {@link ClassPathResource}. - * - * <p>Detects the "file" protocol as well as the JBoss "vfs" protocol in URLs, - * resolving file system references accordingly. - * - * @author Juergen Hoeller - * @since 3.0 - */ -public abstract class AbstractFileResolvingResource extends AbstractResource { - - /** - * This implementation returns a File reference for the underlying class path - * resource, provided that it refers to a file in the file system. - * @see org.springframework.util.ResourceUtils#getFile(java.net.URL, String) - */ - @Override - public File getFile() throws IOException { - URL url = getURL(); - if (url.getProtocol().startsWith(ResourceUtils.URL_PROTOCOL_VFS)) { - return VfsResourceDelegate.getResource(url).getFile(); - } - return ResourceUtils.getFile(url, getDescription()); - } - - /** - * This implementation determines the underlying File - * (or jar file, in case of a resource in a jar/zip). - */ - @Override - protected File getFileForLastModifiedCheck() throws IOException { - URL url = getURL(); - if (ResourceUtils.isJarURL(url)) { - URL actualUrl = ResourceUtils.extractJarFileURL(url); - if (actualUrl.getProtocol().startsWith(ResourceUtils.URL_PROTOCOL_VFS)) { - return VfsResourceDelegate.getResource(actualUrl).getFile(); - } - return ResourceUtils.getFile(actualUrl, "Jar URL"); - } - else { - return getFile(); - } - } - - /** - * This implementation returns a File reference for the underlying class path - * resource, provided that it refers to a file in the file system. - * @see org.springframework.util.ResourceUtils#getFile(java.net.URI, String) - */ - protected File getFile(URI uri) throws IOException { - if (uri.getScheme().startsWith(ResourceUtils.URL_PROTOCOL_VFS)) { - return VfsResourceDelegate.getResource(uri).getFile(); - } - return ResourceUtils.getFile(uri, getDescription()); - } - - - @Override - public boolean exists() { - try { - URL url = getURL(); - if (ResourceUtils.isFileURL(url)) { - // Proceed with file system resolution... - return getFile().exists(); - } - else { - // Try a URL connection content-length header... - URLConnection con = url.openConnection(); - con.setUseCaches(false); - HttpURLConnection httpCon = - (con instanceof HttpURLConnection ? (HttpURLConnection) con : null); - if (httpCon != null) { - httpCon.setRequestMethod("HEAD"); - int code = httpCon.getResponseCode(); - if (code == HttpURLConnection.HTTP_OK) { - return true; - } - else if (code == HttpURLConnection.HTTP_NOT_FOUND) { - return false; - } - } - if (con.getContentLength() >= 0) { - return true; - } - if (httpCon != null) { - // no HTTP OK status, and no content-length header: give up - httpCon.disconnect(); - return false; - } - else { - // Fall back to stream existence: can we open the stream? - InputStream is = getInputStream(); - is.close(); - return true; - } - } - } - catch (IOException ex) { - return false; - } - } - - @Override - public boolean isReadable() { - try { - URL url = getURL(); - if (ResourceUtils.isFileURL(url)) { - // Proceed with file system resolution... - File file = getFile(); - return (file.canRead() && !file.isDirectory()); - } - else { - return true; - } - } - catch (IOException ex) { - return false; - } - } - - @Override - public long contentLength() throws IOException { - URL url = getURL(); - if (ResourceUtils.isFileURL(url)) { - // Proceed with file system resolution... - return super.contentLength(); - } - else { - // Try a URL connection content-length header... - URLConnection con = url.openConnection(); - con.setUseCaches(false); - if (con instanceof HttpURLConnection) { - ((HttpURLConnection) con).setRequestMethod("HEAD"); - } - return con.getContentLength(); - } - } - - @Override - public long lastModified() throws IOException { - URL url = getURL(); - if (ResourceUtils.isFileURL(url) || ResourceUtils.isJarURL(url)) { - // Proceed with file system resolution... - return super.lastModified(); - } - else { - // Try a URL connection last-modified header... - URLConnection con = url.openConnection(); - con.setUseCaches(false); - if (con instanceof HttpURLConnection) { - ((HttpURLConnection) con).setRequestMethod("HEAD"); - } - return con.getLastModified(); - } - } - - - /** - * Inner delegate class, avoiding a hard JBoss VFS API dependency at runtime. - */ - private static class VfsResourceDelegate { - - public static Resource getResource(URL url) throws IOException { - return new VfsResource(VfsUtils.getRoot(url)); - } - - public static Resource getResource(URI uri) throws IOException { - return new VfsResource(VfsUtils.getRoot(uri)); - } - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.core.io; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URI; +import java.net.URL; +import java.net.URLConnection; + +import org.springframework.util.ResourceUtils; + +/** + * Abstract base class for resources which resolve URLs into File references, + * such as {@link UrlResource} or {@link ClassPathResource}. + * + * <p>Detects the "file" protocol as well as the JBoss "vfs" protocol in URLs, + * resolving file system references accordingly. + * + * @author Juergen Hoeller + * @since 3.0 + */ +public abstract class AbstractFileResolvingResource extends AbstractResource { + + /** + * This implementation returns a File reference for the underlying class path + * resource, provided that it refers to a file in the file system. + * @see org.springframework.util.ResourceUtils#getFile(java.net.URL, String) + */ + @Override + public File getFile() throws IOException { + URL url = getURL(); + if (url.getProtocol().startsWith(ResourceUtils.URL_PROTOCOL_VFS)) { + return VfsResourceDelegate.getResource(url).getFile(); + } + return ResourceUtils.getFile(url, getDescription()); + } + + /** + * This implementation determines the underlying File + * (or jar file, in case of a resource in a jar/zip). + */ + @Override + protected File getFileForLastModifiedCheck() throws IOException { + URL url = getURL(); + if (ResourceUtils.isJarURL(url)) { + URL actualUrl = ResourceUtils.extractJarFileURL(url); + if (actualUrl.getProtocol().startsWith(ResourceUtils.URL_PROTOCOL_VFS)) { + return VfsResourceDelegate.getResource(actualUrl).getFile(); + } + return ResourceUtils.getFile(actualUrl, "Jar URL"); + } + else { + return getFile(); + } + } + + /** + * This implementation returns a File reference for the underlying class path + * resource, provided that it refers to a file in the file system. + * @see org.springframework.util.ResourceUtils#getFile(java.net.URI, String) + */ + protected File getFile(URI uri) throws IOException { + if (uri.getScheme().startsWith(ResourceUtils.URL_PROTOCOL_VFS)) { + return VfsResourceDelegate.getResource(uri).getFile(); + } + return ResourceUtils.getFile(uri, getDescription()); + } + + + @Override + public boolean exists() { + try { + URL url = getURL(); + if (ResourceUtils.isFileURL(url)) { + // Proceed with file system resolution... + return getFile().exists(); + } + else { + // Try a URL connection content-length header... + URLConnection con = url.openConnection(); + con.setUseCaches(false); + HttpURLConnection httpCon = + (con instanceof HttpURLConnection ? (HttpURLConnection) con : null); + if (httpCon != null) { + httpCon.setRequestMethod("HEAD"); + int code = httpCon.getResponseCode(); + if (code == HttpURLConnection.HTTP_OK) { + return true; + } + else if (code == HttpURLConnection.HTTP_NOT_FOUND) { + return false; + } + } + if (con.getContentLength() >= 0) { + return true; + } + if (httpCon != null) { + // no HTTP OK status, and no content-length header: give up + httpCon.disconnect(); + return false; + } + else { + // Fall back to stream existence: can we open the stream? + InputStream is = getInputStream(); + is.close(); + return true; + } + } + } + catch (IOException ex) { + return false; + } + } + + @Override + public boolean isReadable() { + try { + URL url = getURL(); + if (ResourceUtils.isFileURL(url)) { + // Proceed with file system resolution... + File file = getFile(); + return (file.canRead() && !file.isDirectory()); + } + else { + return true; + } + } + catch (IOException ex) { + return false; + } + } + + @Override + public long contentLength() throws IOException { + URL url = getURL(); + if (ResourceUtils.isFileURL(url)) { + // Proceed with file system resolution... + return super.contentLength(); + } + else { + // Try a URL connection content-length header... + URLConnection con = url.openConnection(); + con.setUseCaches(false); + if (con instanceof HttpURLConnection) { + ((HttpURLConnection) con).setRequestMethod("HEAD"); + } + return con.getContentLength(); + } + } + + @Override + public long lastModified() throws IOException { + URL url = getURL(); + if (ResourceUtils.isFileURL(url) || ResourceUtils.isJarURL(url)) { + // Proceed with file system resolution... + return super.lastModified(); + } + else { + // Try a URL connection last-modified header... + URLConnection con = url.openConnection(); + con.setUseCaches(false); + if (con instanceof HttpURLConnection) { + ((HttpURLConnection) con).setRequestMethod("HEAD"); + } + return con.getLastModified(); + } + } + + + /** + * Inner delegate class, avoiding a hard JBoss VFS API dependency at runtime. + */ + private static class VfsResourceDelegate { + + public static Resource getResource(URL url) throws IOException { + return new VfsResource(VfsUtils.getRoot(url)); + } + + public static Resource getResource(URI uri) throws IOException { + return new VfsResource(VfsUtils.getRoot(uri)); + } + } + +} diff --git a/org.springframework.core/src/main/java/org/springframework/core/io/ClassRelativeResourceLoader.java b/org.springframework.core/src/main/java/org/springframework/core/io/ClassRelativeResourceLoader.java index dc20e6747fc..d014939b22e 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/io/ClassRelativeResourceLoader.java +++ b/org.springframework.core/src/main/java/org/springframework/core/io/ClassRelativeResourceLoader.java @@ -1,75 +1,75 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.core.io; - -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; - -/** - * {@link ResourceLoader} implementation that interprets plain resource paths - * as relative to a given <code>java.lang.Class</code>. - * - * @author Juergen Hoeller - * @since 3.0 - * @see java.lang.Class#getResource(String) - * @see ClassPathResource#ClassPathResource(String, Class) - */ -public class ClassRelativeResourceLoader extends DefaultResourceLoader { - - private final Class clazz; - - - /** - * Create a new ClassRelativeResourceLoader for the given class. - * @param clazz the class to load resources through - */ - public ClassRelativeResourceLoader(Class clazz) { - Assert.notNull(clazz, "Class must not be null"); - this.clazz = clazz; - setClassLoader(clazz.getClassLoader()); - } - - protected Resource getResourceByPath(String path) { - return new ClassRelativeContextResource(path, this.clazz); - } - - - /** - * ClassPathResource that explicitly expresses a context-relative path - * through implementing the ContextResource interface. - */ - private static class ClassRelativeContextResource extends ClassPathResource implements ContextResource { - - private final Class clazz; - - public ClassRelativeContextResource(String path, Class clazz) { - super(path, clazz); - this.clazz = clazz; - } - - public String getPathWithinContext() { - return getPath(); - } - - @Override - public Resource createRelative(String relativePath) { - String pathToUse = StringUtils.applyRelativePath(getPath(), relativePath); - return new ClassRelativeContextResource(pathToUse, this.clazz); - } - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.core.io; + +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; + +/** + * {@link ResourceLoader} implementation that interprets plain resource paths + * as relative to a given <code>java.lang.Class</code>. + * + * @author Juergen Hoeller + * @since 3.0 + * @see java.lang.Class#getResource(String) + * @see ClassPathResource#ClassPathResource(String, Class) + */ +public class ClassRelativeResourceLoader extends DefaultResourceLoader { + + private final Class clazz; + + + /** + * Create a new ClassRelativeResourceLoader for the given class. + * @param clazz the class to load resources through + */ + public ClassRelativeResourceLoader(Class clazz) { + Assert.notNull(clazz, "Class must not be null"); + this.clazz = clazz; + setClassLoader(clazz.getClassLoader()); + } + + protected Resource getResourceByPath(String path) { + return new ClassRelativeContextResource(path, this.clazz); + } + + + /** + * ClassPathResource that explicitly expresses a context-relative path + * through implementing the ContextResource interface. + */ + private static class ClassRelativeContextResource extends ClassPathResource implements ContextResource { + + private final Class clazz; + + public ClassRelativeContextResource(String path, Class clazz) { + super(path, clazz); + this.clazz = clazz; + } + + public String getPathWithinContext() { + return getPath(); + } + + @Override + public Resource createRelative(String relativePath) { + String pathToUse = StringUtils.applyRelativePath(getPath(), relativePath); + return new ClassRelativeContextResource(pathToUse, this.clazz); + } + } + +} diff --git a/org.springframework.core/src/main/java/org/springframework/core/io/VfsUtils.java b/org.springframework.core/src/main/java/org/springframework/core/io/VfsUtils.java index 5596803b511..a0e268ce702 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/io/VfsUtils.java +++ b/org.springframework.core/src/main/java/org/springframework/core/io/VfsUtils.java @@ -1,253 +1,253 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.core.io; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.net.URI; -import java.net.URL; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.core.NestedIOException; -import org.springframework.util.ReflectionUtils; - -/** - * Utility for detecting the JBoss VFS version available in the classpath. - * JBoss AS 5+ uses VFS 2.x (package <code>org.jboss.virtual</code>) while - * JBoss AS 6+ uses VFS 3.x (package <code>org.jboss.vfs</code>). - * - * <p>Thanks go to Marius Bogoevici for the initial patch. - * - * <b>Note:</b> This is an internal class and should not be used outside the framework. - * - * @author Costin Leau - * @since 3.0.3 - */ -public abstract class VfsUtils { - - private static final Log logger = LogFactory.getLog(VfsUtils.class); - - private static final String VFS2_PKG = "org.jboss.virtual."; - private static final String VFS3_PKG = "org.jboss.vfs."; - private static final String VFS_NAME = "VFS"; - - private static enum VFS_VER { V2, V3 } - - private static VFS_VER version; - - private static Method VFS_METHOD_GET_ROOT_URL = null; - private static Method VFS_METHOD_GET_ROOT_URI = null; - - private static Method VIRTUAL_FILE_METHOD_EXISTS = null; - private static Method VIRTUAL_FILE_METHOD_GET_SIZE; - private static Method VIRTUAL_FILE_METHOD_GET_LAST_MODIFIED; - private static Method VIRTUAL_FILE_METHOD_GET_CHILD; - private static Method VIRTUAL_FILE_METHOD_GET_INPUT_STREAM; - private static Method VIRTUAL_FILE_METHOD_TO_URL; - private static Method VIRTUAL_FILE_METHOD_TO_URI; - private static Method VIRTUAL_FILE_METHOD_GET_NAME; - private static Method VIRTUAL_FILE_METHOD_GET_PATH_NAME; - protected static Class<?> VIRTUAL_FILE_VISITOR_INTERFACE; - protected static Method VIRTUAL_FILE_METHOD_VISIT; - - private static Method VFS_UTILS_METHOD_IS_NESTED_FILE = null; - private static Method VFS_UTILS_METHOD_GET_COMPATIBLE_URI = null; - private static Field VISITOR_ATTRIBUTES_FIELD_RECURSE = null; - private static Method GET_PHYSICAL_FILE = null; - - static { - ClassLoader loader = VfsUtils.class.getClassLoader(); - String pkg; - Class<?> vfsClass; - - // check for JBoss 6 - try { - vfsClass = loader.loadClass(VFS3_PKG + VFS_NAME); - version = VFS_VER.V3; - pkg = VFS3_PKG; - - if (logger.isDebugEnabled()) { - logger.debug("JBoss VFS packages for JBoss AS 6 found"); - } - } - catch (ClassNotFoundException ex) { - // fallback to JBoss 5 - if (logger.isDebugEnabled()) - logger.debug("JBoss VFS packages for JBoss AS 6 not found; falling back to JBoss AS 5 packages"); - try { - vfsClass = loader.loadClass(VFS2_PKG + VFS_NAME); - - version = VFS_VER.V2; - pkg = VFS2_PKG; - - if (logger.isDebugEnabled()) - logger.debug("JBoss VFS packages for JBoss AS 5 found"); - } catch (ClassNotFoundException ex1) { - logger.error("JBoss VFS packages (for both JBoss AS 5 and 6) were not found - JBoss VFS support disabled"); - throw new IllegalStateException("Cannot detect JBoss VFS packages", ex1); - } - } - - // cache reflective information - try { - String methodName = (VFS_VER.V3.equals(version) ? "getChild" : "getRoot"); - - VFS_METHOD_GET_ROOT_URL = ReflectionUtils.findMethod(vfsClass, methodName, URL.class); - VFS_METHOD_GET_ROOT_URI = ReflectionUtils.findMethod(vfsClass, methodName, URI.class); - - Class<?> virtualFile = loader.loadClass(pkg + "VirtualFile"); - - VIRTUAL_FILE_METHOD_EXISTS = ReflectionUtils.findMethod(virtualFile, "exists"); - VIRTUAL_FILE_METHOD_GET_SIZE = ReflectionUtils.findMethod(virtualFile, "getSize"); - VIRTUAL_FILE_METHOD_GET_INPUT_STREAM = ReflectionUtils.findMethod(virtualFile, "openStream"); - VIRTUAL_FILE_METHOD_GET_LAST_MODIFIED = ReflectionUtils.findMethod(virtualFile, "getLastModified"); - VIRTUAL_FILE_METHOD_TO_URI = ReflectionUtils.findMethod(virtualFile, "toURI"); - VIRTUAL_FILE_METHOD_TO_URL = ReflectionUtils.findMethod(virtualFile, "toURL"); - VIRTUAL_FILE_METHOD_GET_NAME = ReflectionUtils.findMethod(virtualFile, "getName"); - VIRTUAL_FILE_METHOD_GET_PATH_NAME = ReflectionUtils.findMethod(virtualFile, "getPathName"); - GET_PHYSICAL_FILE = ReflectionUtils.findMethod(virtualFile, "getPhysicalFile"); - - methodName = (VFS_VER.V3.equals(version) ? "getChild" : "findChild"); - - VIRTUAL_FILE_METHOD_GET_CHILD = ReflectionUtils.findMethod(virtualFile, methodName, String.class); - - Class<?> utilsClass = loader.loadClass(pkg + "VFSUtils"); - - VFS_UTILS_METHOD_GET_COMPATIBLE_URI = ReflectionUtils.findMethod(utilsClass, "getCompatibleURI", - virtualFile); - VFS_UTILS_METHOD_IS_NESTED_FILE = ReflectionUtils.findMethod(utilsClass, "isNestedFile", virtualFile); - - VIRTUAL_FILE_VISITOR_INTERFACE = loader.loadClass(pkg + "VirtualFileVisitor"); - VIRTUAL_FILE_METHOD_VISIT = ReflectionUtils.findMethod(virtualFile, "visit", VIRTUAL_FILE_VISITOR_INTERFACE); - - Class<?> visitorAttributesClass = loader.loadClass(pkg + "VisitorAttributes"); - VISITOR_ATTRIBUTES_FIELD_RECURSE = ReflectionUtils.findField(visitorAttributesClass, "RECURSE"); - } - catch (ClassNotFoundException ex) { - throw new IllegalStateException("Could not detect the JBoss VFS infrastructure", ex); - } - } - - protected static Object invokeVfsMethod(Method method, Object target, Object... args) throws IOException { - try { - return method.invoke(target, args); - } - catch (InvocationTargetException ex) { - Throwable targetEx = ex.getTargetException(); - if (targetEx instanceof IOException) { - throw (IOException) targetEx; - } - ReflectionUtils.handleInvocationTargetException(ex); - } - catch (Exception ex) { - ReflectionUtils.handleReflectionException(ex); - } - - throw new IllegalStateException("Invalid code path reached"); - } - - static boolean exists(Object vfsResource) { - try { - return (Boolean) invokeVfsMethod(VIRTUAL_FILE_METHOD_EXISTS, vfsResource); - } - catch (IOException ex) { - return false; - } - } - - static boolean isReadable(Object vfsResource) { - try { - return ((Long) invokeVfsMethod(VIRTUAL_FILE_METHOD_GET_SIZE, vfsResource) > 0); - } - catch (IOException ex) { - return false; - } - } - - static long getLastModified(Object vfsResource) throws IOException { - return (Long) invokeVfsMethod(VIRTUAL_FILE_METHOD_GET_LAST_MODIFIED, vfsResource); - } - - static InputStream getInputStream(Object vfsResource) throws IOException { - return (InputStream) invokeVfsMethod(VIRTUAL_FILE_METHOD_GET_INPUT_STREAM, vfsResource); - } - - static URL getURL(Object vfsResource) throws IOException { - return (URL) invokeVfsMethod(VIRTUAL_FILE_METHOD_TO_URL, vfsResource); - } - - static URI getURI(Object vfsResource) throws IOException { - return (URI) invokeVfsMethod(VIRTUAL_FILE_METHOD_TO_URI, vfsResource); - } - - static String getName(Object vfsResource) { - try { - return (String) invokeVfsMethod(VIRTUAL_FILE_METHOD_GET_NAME, vfsResource); - } - catch (IOException ex) { - throw new IllegalStateException("Cannot get resource name", ex); - } - } - - static Object getRelative(URL url) throws IOException { - return invokeVfsMethod(VFS_METHOD_GET_ROOT_URL, null, url); - } - - static Object getChild(Object vfsResource, String path) throws IOException { - return invokeVfsMethod(VIRTUAL_FILE_METHOD_GET_CHILD, vfsResource, path); - } - - static File getFile(Object vfsResource) throws IOException { - if (VFS_VER.V2.equals(version)) { - if ((Boolean) invokeVfsMethod(VFS_UTILS_METHOD_IS_NESTED_FILE, null, vfsResource)) { - throw new IOException("File resolution not supported for nested resource: " + vfsResource); - } - try { - return new File((URI) invokeVfsMethod(VFS_UTILS_METHOD_GET_COMPATIBLE_URI, null, vfsResource)); - } - catch (Exception ex) { - throw new NestedIOException("Failed to obtain File reference for " + vfsResource, ex); - } - } - else { - return (File) invokeVfsMethod(GET_PHYSICAL_FILE, vfsResource); - } - } - - static Object getRoot(URI url) throws IOException { - return invokeVfsMethod(VFS_METHOD_GET_ROOT_URI, null, url); - } - - // protected methods used by the support sub-package - - protected static Object getRoot(URL url) throws IOException { - return invokeVfsMethod(VFS_METHOD_GET_ROOT_URL, null, url); - } - - protected static Object doGetVisitorAttribute() { - return ReflectionUtils.getField(VISITOR_ATTRIBUTES_FIELD_RECURSE, null); - } - - protected static String doGetPath(Object resource) { - return (String) ReflectionUtils.invokeMethod(VIRTUAL_FILE_METHOD_GET_PATH_NAME, resource); - } +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.core.io; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.URI; +import java.net.URL; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.core.NestedIOException; +import org.springframework.util.ReflectionUtils; + +/** + * Utility for detecting the JBoss VFS version available in the classpath. + * JBoss AS 5+ uses VFS 2.x (package <code>org.jboss.virtual</code>) while + * JBoss AS 6+ uses VFS 3.x (package <code>org.jboss.vfs</code>). + * + * <p>Thanks go to Marius Bogoevici for the initial patch. + * + * <b>Note:</b> This is an internal class and should not be used outside the framework. + * + * @author Costin Leau + * @since 3.0.3 + */ +public abstract class VfsUtils { + + private static final Log logger = LogFactory.getLog(VfsUtils.class); + + private static final String VFS2_PKG = "org.jboss.virtual."; + private static final String VFS3_PKG = "org.jboss.vfs."; + private static final String VFS_NAME = "VFS"; + + private static enum VFS_VER { V2, V3 } + + private static VFS_VER version; + + private static Method VFS_METHOD_GET_ROOT_URL = null; + private static Method VFS_METHOD_GET_ROOT_URI = null; + + private static Method VIRTUAL_FILE_METHOD_EXISTS = null; + private static Method VIRTUAL_FILE_METHOD_GET_SIZE; + private static Method VIRTUAL_FILE_METHOD_GET_LAST_MODIFIED; + private static Method VIRTUAL_FILE_METHOD_GET_CHILD; + private static Method VIRTUAL_FILE_METHOD_GET_INPUT_STREAM; + private static Method VIRTUAL_FILE_METHOD_TO_URL; + private static Method VIRTUAL_FILE_METHOD_TO_URI; + private static Method VIRTUAL_FILE_METHOD_GET_NAME; + private static Method VIRTUAL_FILE_METHOD_GET_PATH_NAME; + protected static Class<?> VIRTUAL_FILE_VISITOR_INTERFACE; + protected static Method VIRTUAL_FILE_METHOD_VISIT; + + private static Method VFS_UTILS_METHOD_IS_NESTED_FILE = null; + private static Method VFS_UTILS_METHOD_GET_COMPATIBLE_URI = null; + private static Field VISITOR_ATTRIBUTES_FIELD_RECURSE = null; + private static Method GET_PHYSICAL_FILE = null; + + static { + ClassLoader loader = VfsUtils.class.getClassLoader(); + String pkg; + Class<?> vfsClass; + + // check for JBoss 6 + try { + vfsClass = loader.loadClass(VFS3_PKG + VFS_NAME); + version = VFS_VER.V3; + pkg = VFS3_PKG; + + if (logger.isDebugEnabled()) { + logger.debug("JBoss VFS packages for JBoss AS 6 found"); + } + } + catch (ClassNotFoundException ex) { + // fallback to JBoss 5 + if (logger.isDebugEnabled()) + logger.debug("JBoss VFS packages for JBoss AS 6 not found; falling back to JBoss AS 5 packages"); + try { + vfsClass = loader.loadClass(VFS2_PKG + VFS_NAME); + + version = VFS_VER.V2; + pkg = VFS2_PKG; + + if (logger.isDebugEnabled()) + logger.debug("JBoss VFS packages for JBoss AS 5 found"); + } catch (ClassNotFoundException ex1) { + logger.error("JBoss VFS packages (for both JBoss AS 5 and 6) were not found - JBoss VFS support disabled"); + throw new IllegalStateException("Cannot detect JBoss VFS packages", ex1); + } + } + + // cache reflective information + try { + String methodName = (VFS_VER.V3.equals(version) ? "getChild" : "getRoot"); + + VFS_METHOD_GET_ROOT_URL = ReflectionUtils.findMethod(vfsClass, methodName, URL.class); + VFS_METHOD_GET_ROOT_URI = ReflectionUtils.findMethod(vfsClass, methodName, URI.class); + + Class<?> virtualFile = loader.loadClass(pkg + "VirtualFile"); + + VIRTUAL_FILE_METHOD_EXISTS = ReflectionUtils.findMethod(virtualFile, "exists"); + VIRTUAL_FILE_METHOD_GET_SIZE = ReflectionUtils.findMethod(virtualFile, "getSize"); + VIRTUAL_FILE_METHOD_GET_INPUT_STREAM = ReflectionUtils.findMethod(virtualFile, "openStream"); + VIRTUAL_FILE_METHOD_GET_LAST_MODIFIED = ReflectionUtils.findMethod(virtualFile, "getLastModified"); + VIRTUAL_FILE_METHOD_TO_URI = ReflectionUtils.findMethod(virtualFile, "toURI"); + VIRTUAL_FILE_METHOD_TO_URL = ReflectionUtils.findMethod(virtualFile, "toURL"); + VIRTUAL_FILE_METHOD_GET_NAME = ReflectionUtils.findMethod(virtualFile, "getName"); + VIRTUAL_FILE_METHOD_GET_PATH_NAME = ReflectionUtils.findMethod(virtualFile, "getPathName"); + GET_PHYSICAL_FILE = ReflectionUtils.findMethod(virtualFile, "getPhysicalFile"); + + methodName = (VFS_VER.V3.equals(version) ? "getChild" : "findChild"); + + VIRTUAL_FILE_METHOD_GET_CHILD = ReflectionUtils.findMethod(virtualFile, methodName, String.class); + + Class<?> utilsClass = loader.loadClass(pkg + "VFSUtils"); + + VFS_UTILS_METHOD_GET_COMPATIBLE_URI = ReflectionUtils.findMethod(utilsClass, "getCompatibleURI", + virtualFile); + VFS_UTILS_METHOD_IS_NESTED_FILE = ReflectionUtils.findMethod(utilsClass, "isNestedFile", virtualFile); + + VIRTUAL_FILE_VISITOR_INTERFACE = loader.loadClass(pkg + "VirtualFileVisitor"); + VIRTUAL_FILE_METHOD_VISIT = ReflectionUtils.findMethod(virtualFile, "visit", VIRTUAL_FILE_VISITOR_INTERFACE); + + Class<?> visitorAttributesClass = loader.loadClass(pkg + "VisitorAttributes"); + VISITOR_ATTRIBUTES_FIELD_RECURSE = ReflectionUtils.findField(visitorAttributesClass, "RECURSE"); + } + catch (ClassNotFoundException ex) { + throw new IllegalStateException("Could not detect the JBoss VFS infrastructure", ex); + } + } + + protected static Object invokeVfsMethod(Method method, Object target, Object... args) throws IOException { + try { + return method.invoke(target, args); + } + catch (InvocationTargetException ex) { + Throwable targetEx = ex.getTargetException(); + if (targetEx instanceof IOException) { + throw (IOException) targetEx; + } + ReflectionUtils.handleInvocationTargetException(ex); + } + catch (Exception ex) { + ReflectionUtils.handleReflectionException(ex); + } + + throw new IllegalStateException("Invalid code path reached"); + } + + static boolean exists(Object vfsResource) { + try { + return (Boolean) invokeVfsMethod(VIRTUAL_FILE_METHOD_EXISTS, vfsResource); + } + catch (IOException ex) { + return false; + } + } + + static boolean isReadable(Object vfsResource) { + try { + return ((Long) invokeVfsMethod(VIRTUAL_FILE_METHOD_GET_SIZE, vfsResource) > 0); + } + catch (IOException ex) { + return false; + } + } + + static long getLastModified(Object vfsResource) throws IOException { + return (Long) invokeVfsMethod(VIRTUAL_FILE_METHOD_GET_LAST_MODIFIED, vfsResource); + } + + static InputStream getInputStream(Object vfsResource) throws IOException { + return (InputStream) invokeVfsMethod(VIRTUAL_FILE_METHOD_GET_INPUT_STREAM, vfsResource); + } + + static URL getURL(Object vfsResource) throws IOException { + return (URL) invokeVfsMethod(VIRTUAL_FILE_METHOD_TO_URL, vfsResource); + } + + static URI getURI(Object vfsResource) throws IOException { + return (URI) invokeVfsMethod(VIRTUAL_FILE_METHOD_TO_URI, vfsResource); + } + + static String getName(Object vfsResource) { + try { + return (String) invokeVfsMethod(VIRTUAL_FILE_METHOD_GET_NAME, vfsResource); + } + catch (IOException ex) { + throw new IllegalStateException("Cannot get resource name", ex); + } + } + + static Object getRelative(URL url) throws IOException { + return invokeVfsMethod(VFS_METHOD_GET_ROOT_URL, null, url); + } + + static Object getChild(Object vfsResource, String path) throws IOException { + return invokeVfsMethod(VIRTUAL_FILE_METHOD_GET_CHILD, vfsResource, path); + } + + static File getFile(Object vfsResource) throws IOException { + if (VFS_VER.V2.equals(version)) { + if ((Boolean) invokeVfsMethod(VFS_UTILS_METHOD_IS_NESTED_FILE, null, vfsResource)) { + throw new IOException("File resolution not supported for nested resource: " + vfsResource); + } + try { + return new File((URI) invokeVfsMethod(VFS_UTILS_METHOD_GET_COMPATIBLE_URI, null, vfsResource)); + } + catch (Exception ex) { + throw new NestedIOException("Failed to obtain File reference for " + vfsResource, ex); + } + } + else { + return (File) invokeVfsMethod(GET_PHYSICAL_FILE, vfsResource); + } + } + + static Object getRoot(URI url) throws IOException { + return invokeVfsMethod(VFS_METHOD_GET_ROOT_URI, null, url); + } + + // protected methods used by the support sub-package + + protected static Object getRoot(URL url) throws IOException { + return invokeVfsMethod(VFS_METHOD_GET_ROOT_URL, null, url); + } + + protected static Object doGetVisitorAttribute() { + return ReflectionUtils.getField(VISITOR_ATTRIBUTES_FIELD_RECURSE, null); + } + + protected static String doGetPath(Object resource) { + return (String) ReflectionUtils.invokeMethod(VIRTUAL_FILE_METHOD_GET_PATH_NAME, resource); + } } \ No newline at end of file diff --git a/org.springframework.core/src/main/java/org/springframework/core/io/WritableResource.java b/org.springframework.core/src/main/java/org/springframework/core/io/WritableResource.java index c7ec3722c02..1f44c5163eb 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/io/WritableResource.java +++ b/org.springframework.core/src/main/java/org/springframework/core/io/WritableResource.java @@ -1,52 +1,52 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.core.io; - -import java.io.IOException; -import java.io.OutputStream; - -/** - * Extended interface for a resource that supports writing to it. - * Provides an {@link #getOutputStream() OutputStream accessor}. - * - * @author Juergen Hoeller - * @since 3.1 - * @see java.io.OutputStream - */ -public interface WritableResource extends Resource { - - /** - * Return whether the contents of this resource can be modified, - * e.g. via {@link #getOutputStream()} or {@link #getFile()}. - * <p>Will be <code>true</code> for typical resource descriptors; - * note that actual content writing may still fail when attempted. - * However, a value of <code>false</code> is a definitive indication - * that the resource content cannot be modified. - * @see #getOutputStream() - * @see #isReadable() - */ - boolean isWritable(); - - /** - * Return an {@link OutputStream} for the underlying resource, - * allowing to (over-)write its content. - * @throws IOException if the stream could not be opened - * @see #getInputStream() - */ - OutputStream getOutputStream() throws IOException; - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.core.io; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * Extended interface for a resource that supports writing to it. + * Provides an {@link #getOutputStream() OutputStream accessor}. + * + * @author Juergen Hoeller + * @since 3.1 + * @see java.io.OutputStream + */ +public interface WritableResource extends Resource { + + /** + * Return whether the contents of this resource can be modified, + * e.g. via {@link #getOutputStream()} or {@link #getFile()}. + * <p>Will be <code>true</code> for typical resource descriptors; + * note that actual content writing may still fail when attempted. + * However, a value of <code>false</code> is a definitive indication + * that the resource content cannot be modified. + * @see #getOutputStream() + * @see #isReadable() + */ + boolean isWritable(); + + /** + * Return an {@link OutputStream} for the underlying resource, + * allowing to (over-)write its content. + * @throws IOException if the stream could not be opened + * @see #getInputStream() + */ + OutputStream getOutputStream() throws IOException; + +} diff --git a/org.springframework.core/src/main/java/org/springframework/core/io/support/VfsPatternUtils.java b/org.springframework.core/src/main/java/org/springframework/core/io/support/VfsPatternUtils.java index 44adbf2197f..f6e523ea586 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/io/support/VfsPatternUtils.java +++ b/org.springframework.core/src/main/java/org/springframework/core/io/support/VfsPatternUtils.java @@ -1,53 +1,53 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.core.io.support; - -import java.io.IOException; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Proxy; -import java.net.URL; - -import org.springframework.core.io.VfsUtils; - -/** - * Artificial class used for accessing the {@link VfsUtils} methods - * without exposing them to the entire world. - * - * @author Costin Leau - * @since 3.0.3 - */ -abstract class VfsPatternUtils extends VfsUtils { - - static Object getVisitorAttribute() { - return doGetVisitorAttribute(); - } - - static String getPath(Object resource) { - return doGetPath(resource); - } - - static Object findRoot(URL url) throws IOException { - return getRoot(url); - } - - static void visit(Object resource, InvocationHandler visitor) throws IOException { - Object visitorProxy = Proxy.newProxyInstance(VIRTUAL_FILE_VISITOR_INTERFACE.getClassLoader(), - new Class<?>[] { VIRTUAL_FILE_VISITOR_INTERFACE }, visitor); - invokeVfsMethod(VIRTUAL_FILE_METHOD_VISIT, resource, visitorProxy); - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.core.io.support; + +import java.io.IOException; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Proxy; +import java.net.URL; + +import org.springframework.core.io.VfsUtils; + +/** + * Artificial class used for accessing the {@link VfsUtils} methods + * without exposing them to the entire world. + * + * @author Costin Leau + * @since 3.0.3 + */ +abstract class VfsPatternUtils extends VfsUtils { + + static Object getVisitorAttribute() { + return doGetVisitorAttribute(); + } + + static String getPath(Object resource) { + return doGetPath(resource); + } + + static Object findRoot(URL url) throws IOException { + return getRoot(url); + } + + static void visit(Object resource, InvocationHandler visitor) throws IOException { + Object visitorProxy = Proxy.newProxyInstance(VIRTUAL_FILE_VISITOR_INTERFACE.getClassLoader(), + new Class<?>[] { VIRTUAL_FILE_VISITOR_INTERFACE }, visitor); + invokeVfsMethod(VIRTUAL_FILE_METHOD_VISIT, resource, visitorProxy); + } + +} diff --git a/org.springframework.core/src/main/java/org/springframework/core/serializer/support/package-info.java b/org.springframework.core/src/main/java/org/springframework/core/serializer/support/package-info.java index 22c3c03a8f1..33f7365ffb5 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/serializer/support/package-info.java +++ b/org.springframework.core/src/main/java/org/springframework/core/serializer/support/package-info.java @@ -1,9 +1,9 @@ - -/** - * - * Support classes for Spring's serializer abstraction. - * Includes adapters to the Converter SPI. - * - */ -package org.springframework.core.serializer.support; - + +/** + * + * Support classes for Spring's serializer abstraction. + * Includes adapters to the Converter SPI. + * + */ +package org.springframework.core.serializer.support; + diff --git a/org.springframework.core/src/main/java/org/springframework/core/task/support/ExecutorServiceAdapter.java b/org.springframework.core/src/main/java/org/springframework/core/task/support/ExecutorServiceAdapter.java index 323df6eedec..91d5122d848 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/task/support/ExecutorServiceAdapter.java +++ b/org.springframework.core/src/main/java/org/springframework/core/task/support/ExecutorServiceAdapter.java @@ -1,87 +1,87 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.core.task.support; - -import java.util.List; -import java.util.concurrent.AbstractExecutorService; -import java.util.concurrent.TimeUnit; - -import org.springframework.core.task.TaskExecutor; -import org.springframework.util.Assert; - -/** - * Adapter that takes a Spring {@link org.springframework.core.task.TaskExecutor}) - * and exposes a full <code>java.util.concurrent.ExecutorService</code> for it. - * - * <p>This is primarily for adapting to client components that communicate via the - * <code>java.util.concurrent.ExecutorService</code> API. It can also be used as - * common ground between a local Spring <code>TaskExecutor</code> backend and a - * JNDI-located <code>ManagedExecutorService</code> in a Java EE 6 environment. - * - * <p><b>NOTE:</b> This ExecutorService adapter does <em>not</em> support the - * lifecycle methods in the <code>java.util.concurrent.ExecutorService</code> API - * ("shutdown()" etc), similar to a server-wide <code>ManagedExecutorService</code> - * in a Java EE 6 environment. The lifecycle is always up to the backend pool, - * with this adapter acting as an access-only proxy for that target pool. - * - * @author Juergen Hoeller - * @since 3.0 - * @see java.util.concurrent.ExecutorService - */ -public class ExecutorServiceAdapter extends AbstractExecutorService { - - private final TaskExecutor taskExecutor; - - - /** - * Create a new ExecutorServiceAdapter, using the given target executor. - * @param concurrentExecutor the target executor to delegate to - */ - public ExecutorServiceAdapter(TaskExecutor taskExecutor) { - Assert.notNull(taskExecutor, "TaskExecutor must not be null"); - this.taskExecutor = taskExecutor; - } - - - public void execute(Runnable task) { - this.taskExecutor.execute(task); - } - - public void shutdown() { - throw new IllegalStateException( - "Manual shutdown not supported - ExecutorServiceAdapter is dependent on an external lifecycle"); - } - - public List<Runnable> shutdownNow() { - throw new IllegalStateException( - "Manual shutdown not supported - ExecutorServiceAdapter is dependent on an external lifecycle"); - } - - public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException { - throw new IllegalStateException( - "Manual shutdown not supported - ExecutorServiceAdapter is dependent on an external lifecycle"); - } - - public boolean isShutdown() { - return false; - } - - public boolean isTerminated() { - return false; - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.core.task.support; + +import java.util.List; +import java.util.concurrent.AbstractExecutorService; +import java.util.concurrent.TimeUnit; + +import org.springframework.core.task.TaskExecutor; +import org.springframework.util.Assert; + +/** + * Adapter that takes a Spring {@link org.springframework.core.task.TaskExecutor}) + * and exposes a full <code>java.util.concurrent.ExecutorService</code> for it. + * + * <p>This is primarily for adapting to client components that communicate via the + * <code>java.util.concurrent.ExecutorService</code> API. It can also be used as + * common ground between a local Spring <code>TaskExecutor</code> backend and a + * JNDI-located <code>ManagedExecutorService</code> in a Java EE 6 environment. + * + * <p><b>NOTE:</b> This ExecutorService adapter does <em>not</em> support the + * lifecycle methods in the <code>java.util.concurrent.ExecutorService</code> API + * ("shutdown()" etc), similar to a server-wide <code>ManagedExecutorService</code> + * in a Java EE 6 environment. The lifecycle is always up to the backend pool, + * with this adapter acting as an access-only proxy for that target pool. + * + * @author Juergen Hoeller + * @since 3.0 + * @see java.util.concurrent.ExecutorService + */ +public class ExecutorServiceAdapter extends AbstractExecutorService { + + private final TaskExecutor taskExecutor; + + + /** + * Create a new ExecutorServiceAdapter, using the given target executor. + * @param concurrentExecutor the target executor to delegate to + */ + public ExecutorServiceAdapter(TaskExecutor taskExecutor) { + Assert.notNull(taskExecutor, "TaskExecutor must not be null"); + this.taskExecutor = taskExecutor; + } + + + public void execute(Runnable task) { + this.taskExecutor.execute(task); + } + + public void shutdown() { + throw new IllegalStateException( + "Manual shutdown not supported - ExecutorServiceAdapter is dependent on an external lifecycle"); + } + + public List<Runnable> shutdownNow() { + throw new IllegalStateException( + "Manual shutdown not supported - ExecutorServiceAdapter is dependent on an external lifecycle"); + } + + public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException { + throw new IllegalStateException( + "Manual shutdown not supported - ExecutorServiceAdapter is dependent on an external lifecycle"); + } + + public boolean isShutdown() { + return false; + } + + public boolean isTerminated() { + return false; + } + +} diff --git a/org.springframework.core/src/main/java/org/springframework/core/type/MethodMetadata.java b/org.springframework.core/src/main/java/org/springframework/core/type/MethodMetadata.java index b9417e8873d..21f715e764f 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/type/MethodMetadata.java +++ b/org.springframework.core/src/main/java/org/springframework/core/type/MethodMetadata.java @@ -1,79 +1,79 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.core.type; - -import java.util.Map; - -/** - * Interface that defines abstract access to the annotations of a specific - * class, in a form that does not require that class to be loaded yet. - * - * @author Juergen Hoeller - * @author Mark Pollack - * @author Chris Beams - * @since 3.0 - * @see StandardMethodMetadata - * @see AnnotationMetadata#getAnnotatedMethods - */ -public interface MethodMetadata { - - /** - * Return the name of the method. - */ - String getMethodName(); - - /** - * Return the fully-qualified name of the class that declares this method. - */ - public String getDeclaringClassName(); - - /** - * Return whether the underlying method is declared as 'static'. - */ - boolean isStatic(); - - /** - * Return whether the underlying method is marked as 'final'. - */ - boolean isFinal(); - - /** - * Return whether the underlying method is overridable, - * i.e. not marked as static, final or private. - */ - boolean isOverridable(); - - /** - * Determine whether the underlying method has an annotation or - * meta-annotation of the given type defined. - * @param annotationType the annotation type to look for - * @return whether a matching annotation is defined - */ - boolean isAnnotated(String annotationType); - - /** - * Retrieve the attributes of the annotation of the given type, - * if any (i.e. if defined on the underlying method, as direct - * annotation or as meta-annotation). - * @param annotationType the annotation type to look for - * @return a Map of attributes, with the attribute name as key (e.g. "value") - * and the defined attribute value as Map value. This return value will be - * <code>null</code> if no matching annotation is defined. - */ - Map<String, Object> getAnnotationAttributes(String annotationType); - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.core.type; + +import java.util.Map; + +/** + * Interface that defines abstract access to the annotations of a specific + * class, in a form that does not require that class to be loaded yet. + * + * @author Juergen Hoeller + * @author Mark Pollack + * @author Chris Beams + * @since 3.0 + * @see StandardMethodMetadata + * @see AnnotationMetadata#getAnnotatedMethods + */ +public interface MethodMetadata { + + /** + * Return the name of the method. + */ + String getMethodName(); + + /** + * Return the fully-qualified name of the class that declares this method. + */ + public String getDeclaringClassName(); + + /** + * Return whether the underlying method is declared as 'static'. + */ + boolean isStatic(); + + /** + * Return whether the underlying method is marked as 'final'. + */ + boolean isFinal(); + + /** + * Return whether the underlying method is overridable, + * i.e. not marked as static, final or private. + */ + boolean isOverridable(); + + /** + * Determine whether the underlying method has an annotation or + * meta-annotation of the given type defined. + * @param annotationType the annotation type to look for + * @return whether a matching annotation is defined + */ + boolean isAnnotated(String annotationType); + + /** + * Retrieve the attributes of the annotation of the given type, + * if any (i.e. if defined on the underlying method, as direct + * annotation or as meta-annotation). + * @param annotationType the annotation type to look for + * @return a Map of attributes, with the attribute name as key (e.g. "value") + * and the defined attribute value as Map value. This return value will be + * <code>null</code> if no matching annotation is defined. + */ + Map<String, Object> getAnnotationAttributes(String annotationType); + +} diff --git a/org.springframework.core/src/main/java/org/springframework/core/type/StandardMethodMetadata.java b/org.springframework.core/src/main/java/org/springframework/core/type/StandardMethodMetadata.java index c6c8f28f80e..ead840cc21b 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/type/StandardMethodMetadata.java +++ b/org.springframework.core/src/main/java/org/springframework/core/type/StandardMethodMetadata.java @@ -1,108 +1,108 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.core.type; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.Map; - -import org.springframework.core.annotation.AnnotationUtils; -import org.springframework.util.Assert; - -/** - * {@link MethodMetadata} implementation that uses standard reflection - * to introspect a given <code>Method</code>. - * - * @author Juergen Hoeller - * @author Mark Pollack - * @author Chris Beams - * @since 3.0 - */ -public class StandardMethodMetadata implements MethodMetadata { - - private final Method introspectedMethod; - - - /** - * Create a new StandardMethodMetadata wrapper for the given Method. - * @param introspectedMethod the Method to introspect - */ - public StandardMethodMetadata(Method introspectedMethod) { - Assert.notNull(introspectedMethod, "Method must not be null"); - this.introspectedMethod = introspectedMethod; - } - - /** - * Return the underlying Method. - */ - public final Method getIntrospectedMethod() { - return this.introspectedMethod; - } - - - public String getMethodName() { - return this.introspectedMethod.getName(); - } - - public String getDeclaringClassName() { - return this.introspectedMethod.getDeclaringClass().getName(); - } - - public boolean isStatic() { - return Modifier.isStatic(this.introspectedMethod.getModifiers()); - } - - public boolean isFinal() { - return Modifier.isFinal(this.introspectedMethod.getModifiers()); - } - - public boolean isOverridable() { - return (!isStatic() && !isFinal() && !Modifier.isPrivate(this.introspectedMethod.getModifiers())); - } - - public boolean isAnnotated(String annotationType) { - Annotation[] anns = this.introspectedMethod.getAnnotations(); - for (Annotation ann : anns) { - if (ann.annotationType().getName().equals(annotationType)) { - return true; - } - for (Annotation metaAnn : ann.annotationType().getAnnotations()) { - if (metaAnn.annotationType().getName().equals(annotationType)) { - return true; - } - } - } - return false; - } - - public Map<String, Object> getAnnotationAttributes(String annotationType) { - Annotation[] anns = this.introspectedMethod.getAnnotations(); - for (Annotation ann : anns) { - if (ann.annotationType().getName().equals(annotationType)) { - return AnnotationUtils.getAnnotationAttributes(ann, true); - } - for (Annotation metaAnn : ann.annotationType().getAnnotations()) { - if (metaAnn.annotationType().getName().equals(annotationType)) { - return AnnotationUtils.getAnnotationAttributes(metaAnn, true); - } - } - } - return null; - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.core.type; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.Map; + +import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.util.Assert; + +/** + * {@link MethodMetadata} implementation that uses standard reflection + * to introspect a given <code>Method</code>. + * + * @author Juergen Hoeller + * @author Mark Pollack + * @author Chris Beams + * @since 3.0 + */ +public class StandardMethodMetadata implements MethodMetadata { + + private final Method introspectedMethod; + + + /** + * Create a new StandardMethodMetadata wrapper for the given Method. + * @param introspectedMethod the Method to introspect + */ + public StandardMethodMetadata(Method introspectedMethod) { + Assert.notNull(introspectedMethod, "Method must not be null"); + this.introspectedMethod = introspectedMethod; + } + + /** + * Return the underlying Method. + */ + public final Method getIntrospectedMethod() { + return this.introspectedMethod; + } + + + public String getMethodName() { + return this.introspectedMethod.getName(); + } + + public String getDeclaringClassName() { + return this.introspectedMethod.getDeclaringClass().getName(); + } + + public boolean isStatic() { + return Modifier.isStatic(this.introspectedMethod.getModifiers()); + } + + public boolean isFinal() { + return Modifier.isFinal(this.introspectedMethod.getModifiers()); + } + + public boolean isOverridable() { + return (!isStatic() && !isFinal() && !Modifier.isPrivate(this.introspectedMethod.getModifiers())); + } + + public boolean isAnnotated(String annotationType) { + Annotation[] anns = this.introspectedMethod.getAnnotations(); + for (Annotation ann : anns) { + if (ann.annotationType().getName().equals(annotationType)) { + return true; + } + for (Annotation metaAnn : ann.annotationType().getAnnotations()) { + if (metaAnn.annotationType().getName().equals(annotationType)) { + return true; + } + } + } + return false; + } + + public Map<String, Object> getAnnotationAttributes(String annotationType) { + Annotation[] anns = this.introspectedMethod.getAnnotations(); + for (Annotation ann : anns) { + if (ann.annotationType().getName().equals(annotationType)) { + return AnnotationUtils.getAnnotationAttributes(ann, true); + } + for (Annotation metaAnn : ann.annotationType().getAnnotations()) { + if (metaAnn.annotationType().getName().equals(annotationType)) { + return AnnotationUtils.getAnnotationAttributes(metaAnn, true); + } + } + } + return null; + } + +} diff --git a/org.springframework.core/src/main/java/org/springframework/core/type/classreading/AnnotationAttributesReadingVisitor.java b/org.springframework.core/src/main/java/org/springframework/core/type/classreading/AnnotationAttributesReadingVisitor.java index 267dc6c5d67..244808b3235 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/type/classreading/AnnotationAttributesReadingVisitor.java +++ b/org.springframework.core/src/main/java/org/springframework/core/type/classreading/AnnotationAttributesReadingVisitor.java @@ -1,150 +1,150 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.core.type.classreading; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Array; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Set; - -import org.springframework.asm.AnnotationVisitor; -import org.springframework.asm.Type; -import org.springframework.asm.commons.EmptyVisitor; -import org.springframework.core.annotation.AnnotationUtils; -import org.springframework.util.ObjectUtils; -import org.springframework.util.ReflectionUtils; - -/** - * ASM visitor which looks for the annotations defined on a class or method. - * - * @author Juergen Hoeller - * @since 3.0 - */ -final class AnnotationAttributesReadingVisitor implements AnnotationVisitor { - - private final String annotationType; - - private final Map<String, Map<String, Object>> attributesMap; - - private final Map<String, Set<String>> metaAnnotationMap; - - private final ClassLoader classLoader; - - private final Map<String, Object> localAttributes = new LinkedHashMap<String, Object>(); - - - public AnnotationAttributesReadingVisitor( - String annotationType, Map<String, Map<String, Object>> attributesMap, - Map<String, Set<String>> metaAnnotationMap, ClassLoader classLoader) { - - this.annotationType = annotationType; - this.attributesMap = attributesMap; - this.metaAnnotationMap = metaAnnotationMap; - this.classLoader = classLoader; - } - - - public void visit(String name, Object value) { - this.localAttributes.put(name, value); - } - - public void visitEnum(String name, String desc, String value) { - Object valueToUse = value; - try { - Class<?> enumType = this.classLoader.loadClass(Type.getType(desc).getClassName()); - Field enumConstant = ReflectionUtils.findField(enumType, value); - if (enumConstant != null) { - valueToUse = enumConstant.get(null); - } - } - catch (Exception ex) { - // Class not found - can't resolve class reference in annotation attribute. - } - this.localAttributes.put(name, valueToUse); - } - - public AnnotationVisitor visitAnnotation(String name, String desc) { - return new EmptyVisitor(); - } - - public AnnotationVisitor visitArray(final String attrName) { - return new AnnotationVisitor() { - public void visit(String name, Object value) { - Object newValue = value; - Object existingValue = localAttributes.get(attrName); - if (existingValue != null) { - newValue = ObjectUtils.addObjectToArray((Object[]) existingValue, newValue); - } - else { - Object[] newArray = (Object[]) Array.newInstance(newValue.getClass(), 1); - newArray[0] = newValue; - newValue = newArray; - } - localAttributes.put(attrName, newValue); - } - public void visitEnum(String name, String desc, String value) { - } - public AnnotationVisitor visitAnnotation(String name, String desc) { - return new EmptyVisitor(); - } - public AnnotationVisitor visitArray(String name) { - return new EmptyVisitor(); - } - public void visitEnd() { - } - }; - } - - public void visitEnd() { - this.attributesMap.put(this.annotationType, this.localAttributes); - try { - Class<?> annotationClass = this.classLoader.loadClass(this.annotationType); - // Check declared default values of attributes in the annotation type. - Method[] annotationAttributes = annotationClass.getMethods(); - for (Method annotationAttribute : annotationAttributes) { - String attributeName = annotationAttribute.getName(); - Object defaultValue = annotationAttribute.getDefaultValue(); - if (defaultValue != null && !this.localAttributes.containsKey(attributeName)) { - this.localAttributes.put(attributeName, defaultValue); - } - } - // Register annotations that the annotation type is annotated with. - Set<String> metaAnnotationTypeNames = new LinkedHashSet<String>(); - for (Annotation metaAnnotation : annotationClass.getAnnotations()) { - metaAnnotationTypeNames.add(metaAnnotation.annotationType().getName()); - if (!this.attributesMap.containsKey(metaAnnotation.annotationType().getName())) { - this.attributesMap.put(metaAnnotation.annotationType().getName(), - AnnotationUtils.getAnnotationAttributes(metaAnnotation, true)); - } - for (Annotation metaMetaAnnotation : metaAnnotation.annotationType().getAnnotations()) { - metaAnnotationTypeNames.add(metaMetaAnnotation.annotationType().getName()); - } - } - if (this.metaAnnotationMap != null) { - this.metaAnnotationMap.put(this.annotationType, metaAnnotationTypeNames); - } - } - catch (ClassNotFoundException ex) { - // Class not found - can't determine meta-annotations. - } - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.core.type.classreading; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Array; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + +import org.springframework.asm.AnnotationVisitor; +import org.springframework.asm.Type; +import org.springframework.asm.commons.EmptyVisitor; +import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.util.ObjectUtils; +import org.springframework.util.ReflectionUtils; + +/** + * ASM visitor which looks for the annotations defined on a class or method. + * + * @author Juergen Hoeller + * @since 3.0 + */ +final class AnnotationAttributesReadingVisitor implements AnnotationVisitor { + + private final String annotationType; + + private final Map<String, Map<String, Object>> attributesMap; + + private final Map<String, Set<String>> metaAnnotationMap; + + private final ClassLoader classLoader; + + private final Map<String, Object> localAttributes = new LinkedHashMap<String, Object>(); + + + public AnnotationAttributesReadingVisitor( + String annotationType, Map<String, Map<String, Object>> attributesMap, + Map<String, Set<String>> metaAnnotationMap, ClassLoader classLoader) { + + this.annotationType = annotationType; + this.attributesMap = attributesMap; + this.metaAnnotationMap = metaAnnotationMap; + this.classLoader = classLoader; + } + + + public void visit(String name, Object value) { + this.localAttributes.put(name, value); + } + + public void visitEnum(String name, String desc, String value) { + Object valueToUse = value; + try { + Class<?> enumType = this.classLoader.loadClass(Type.getType(desc).getClassName()); + Field enumConstant = ReflectionUtils.findField(enumType, value); + if (enumConstant != null) { + valueToUse = enumConstant.get(null); + } + } + catch (Exception ex) { + // Class not found - can't resolve class reference in annotation attribute. + } + this.localAttributes.put(name, valueToUse); + } + + public AnnotationVisitor visitAnnotation(String name, String desc) { + return new EmptyVisitor(); + } + + public AnnotationVisitor visitArray(final String attrName) { + return new AnnotationVisitor() { + public void visit(String name, Object value) { + Object newValue = value; + Object existingValue = localAttributes.get(attrName); + if (existingValue != null) { + newValue = ObjectUtils.addObjectToArray((Object[]) existingValue, newValue); + } + else { + Object[] newArray = (Object[]) Array.newInstance(newValue.getClass(), 1); + newArray[0] = newValue; + newValue = newArray; + } + localAttributes.put(attrName, newValue); + } + public void visitEnum(String name, String desc, String value) { + } + public AnnotationVisitor visitAnnotation(String name, String desc) { + return new EmptyVisitor(); + } + public AnnotationVisitor visitArray(String name) { + return new EmptyVisitor(); + } + public void visitEnd() { + } + }; + } + + public void visitEnd() { + this.attributesMap.put(this.annotationType, this.localAttributes); + try { + Class<?> annotationClass = this.classLoader.loadClass(this.annotationType); + // Check declared default values of attributes in the annotation type. + Method[] annotationAttributes = annotationClass.getMethods(); + for (Method annotationAttribute : annotationAttributes) { + String attributeName = annotationAttribute.getName(); + Object defaultValue = annotationAttribute.getDefaultValue(); + if (defaultValue != null && !this.localAttributes.containsKey(attributeName)) { + this.localAttributes.put(attributeName, defaultValue); + } + } + // Register annotations that the annotation type is annotated with. + Set<String> metaAnnotationTypeNames = new LinkedHashSet<String>(); + for (Annotation metaAnnotation : annotationClass.getAnnotations()) { + metaAnnotationTypeNames.add(metaAnnotation.annotationType().getName()); + if (!this.attributesMap.containsKey(metaAnnotation.annotationType().getName())) { + this.attributesMap.put(metaAnnotation.annotationType().getName(), + AnnotationUtils.getAnnotationAttributes(metaAnnotation, true)); + } + for (Annotation metaMetaAnnotation : metaAnnotation.annotationType().getAnnotations()) { + metaAnnotationTypeNames.add(metaMetaAnnotation.annotationType().getName()); + } + } + if (this.metaAnnotationMap != null) { + this.metaAnnotationMap.put(this.annotationType, metaAnnotationTypeNames); + } + } + catch (ClassNotFoundException ex) { + // Class not found - can't determine meta-annotations. + } + } + +} diff --git a/org.springframework.core/src/main/java/org/springframework/util/CompositeIterator.java b/org.springframework.core/src/main/java/org/springframework/util/CompositeIterator.java index 67935ae6b4c..1e70018f5c2 100644 --- a/org.springframework.core/src/main/java/org/springframework/util/CompositeIterator.java +++ b/org.springframework.core/src/main/java/org/springframework/util/CompositeIterator.java @@ -1,75 +1,75 @@ -/* - * Copyright 2004-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.util; - -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.NoSuchElementException; - -/** - * Iterator that combines multiple other iterators. - * This implementation maintains a list of iterators which are invoked in sequence until all iterators are exhausted. - * @author Erwin Vervaet - */ -public class CompositeIterator<E> implements Iterator<E> { - - private List<Iterator<E>> iterators = new LinkedList<Iterator<E>>(); - - private boolean inUse = false; - - /** - * Create a new composite iterator. Add iterators using the {@link #add(Iterator)} method. - */ - public CompositeIterator() { - } - - /** - * Add given iterator to this composite. - */ - public void add(Iterator<E> iterator) { - Assert.state(!inUse, "You can no longer add iterator to a composite iterator that's already in use"); - if (iterators.contains(iterator)) { - throw new IllegalArgumentException("You cannot add the same iterator twice"); - } - iterators.add(iterator); - } - - public boolean hasNext() { - inUse = true; - for (Iterator<Iterator<E>> it = iterators.iterator(); it.hasNext();) { - if (it.next().hasNext()) { - return true; - } - } - return false; - } - - public E next() { - inUse = true; - for (Iterator<Iterator<E>> it = iterators.iterator(); it.hasNext();) { - Iterator<E> iterator = it.next(); - if (iterator.hasNext()) { - return iterator.next(); - } - } - throw new NoSuchElementException("Exhaused all iterators"); - } - - public void remove() { - throw new UnsupportedOperationException("Remove is not supported"); - } +/* + * Copyright 2004-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.util; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.NoSuchElementException; + +/** + * Iterator that combines multiple other iterators. + * This implementation maintains a list of iterators which are invoked in sequence until all iterators are exhausted. + * @author Erwin Vervaet + */ +public class CompositeIterator<E> implements Iterator<E> { + + private List<Iterator<E>> iterators = new LinkedList<Iterator<E>>(); + + private boolean inUse = false; + + /** + * Create a new composite iterator. Add iterators using the {@link #add(Iterator)} method. + */ + public CompositeIterator() { + } + + /** + * Add given iterator to this composite. + */ + public void add(Iterator<E> iterator) { + Assert.state(!inUse, "You can no longer add iterator to a composite iterator that's already in use"); + if (iterators.contains(iterator)) { + throw new IllegalArgumentException("You cannot add the same iterator twice"); + } + iterators.add(iterator); + } + + public boolean hasNext() { + inUse = true; + for (Iterator<Iterator<E>> it = iterators.iterator(); it.hasNext();) { + if (it.next().hasNext()) { + return true; + } + } + return false; + } + + public E next() { + inUse = true; + for (Iterator<Iterator<E>> it = iterators.iterator(); it.hasNext();) { + Iterator<E> iterator = it.next(); + if (iterator.hasNext()) { + return iterator.next(); + } + } + throw new NoSuchElementException("Exhaused all iterators"); + } + + public void remove() { + throw new UnsupportedOperationException("Remove is not supported"); + } } \ No newline at end of file diff --git a/org.springframework.core/src/main/java/org/springframework/util/LinkedCaseInsensitiveMap.java b/org.springframework.core/src/main/java/org/springframework/util/LinkedCaseInsensitiveMap.java index e5df7256ec4..a756f3d34a0 100644 --- a/org.springframework.core/src/main/java/org/springframework/util/LinkedCaseInsensitiveMap.java +++ b/org.springframework.core/src/main/java/org/springframework/util/LinkedCaseInsensitiveMap.java @@ -1,149 +1,149 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.util; - -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Locale; -import java.util.Map; - -/** - * {@link LinkedHashMap} variant that stores String keys in a case-insensitive - * manner, for example for key-based access in a results table. - * - * <p>Preserves the original order as well as the original casing of keys, - * while allowing for contains, get and remove calls with any case of key. - * - * <p>Does <i>not</i> support <code>null</code> keys. - * - * @author Juergen Hoeller - * @since 3.0 - */ -public class LinkedCaseInsensitiveMap<V> extends LinkedHashMap<String, V> { - - private final Map<String, String> caseInsensitiveKeys; - - private final Locale locale; - - - /** - * Create a new LinkedCaseInsensitiveMap for the default Locale. - * @see java.lang.String#toLowerCase() - */ - public LinkedCaseInsensitiveMap() { - this(null); - } - - /** - * Create a new LinkedCaseInsensitiveMap that stores lower-case keys - * according to the given Locale. - * @param locale the Locale to use for lower-case conversion - * @see java.lang.String#toLowerCase(java.util.Locale) - */ - public LinkedCaseInsensitiveMap(Locale locale) { - super(); - this.caseInsensitiveKeys = new HashMap<String, String>(); - this.locale = (locale != null ? locale : Locale.getDefault()); - } - - /** - * Create a new LinkedCaseInsensitiveMap that wraps a {@link LinkedHashMap} - * with the given initial capacity and stores lower-case keys according - * to the default Locale. - * @param initialCapacity the initial capacity - * @see java.lang.String#toLowerCase() - */ - public LinkedCaseInsensitiveMap(int initialCapacity) { - this(initialCapacity, null); - } - - /** - * Create a new LinkedCaseInsensitiveMap that wraps a {@link LinkedHashMap} - * with the given initial capacity and stores lower-case keys according - * to the given Locale. - * @param initialCapacity the initial capacity - * @param locale the Locale to use for lower-case conversion - * @see java.lang.String#toLowerCase(java.util.Locale) - */ - public LinkedCaseInsensitiveMap(int initialCapacity, Locale locale) { - super(initialCapacity); - this.caseInsensitiveKeys = new HashMap<String, String>(initialCapacity); - this.locale = (locale != null ? locale : Locale.getDefault()); - } - - - @Override - public V put(String key, V value) { - this.caseInsensitiveKeys.put(convertKey(key), key); - return super.put(key, value); - } - - @Override - public void putAll(Map<? extends String, ? extends V> map) { - if (map.isEmpty()) { - return; - } - for (Map.Entry<? extends String, ? extends V> entry : map.entrySet()) { - put(entry.getKey(), entry.getValue()); - } - } - - @Override - public boolean containsKey(Object key) { - return (key instanceof String && this.caseInsensitiveKeys.containsKey(convertKey((String) key))); - } - - @Override - public V get(Object key) { - if (key instanceof String) { - return super.get(this.caseInsensitiveKeys.get(convertKey((String) key))); - } - else { - return null; - } - } - - @Override - public V remove(Object key) { - if (key instanceof String ) { - return super.remove(this.caseInsensitiveKeys.remove(convertKey((String) key))); - } - else { - return null; - } - } - - @Override - public void clear() { - this.caseInsensitiveKeys.clear(); - super.clear(); - } - - - /** - * Convert the given key to a case-insensitive key. - * <p>The default implementation converts the key - * to lower-case according to this Map's Locale. - * @param key the user-specified key - * @return the key to use for storing - * @see java.lang.String#toLowerCase(java.util.Locale) - */ - protected String convertKey(String key) { - return key.toLowerCase(this.locale); - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.util; + +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Locale; +import java.util.Map; + +/** + * {@link LinkedHashMap} variant that stores String keys in a case-insensitive + * manner, for example for key-based access in a results table. + * + * <p>Preserves the original order as well as the original casing of keys, + * while allowing for contains, get and remove calls with any case of key. + * + * <p>Does <i>not</i> support <code>null</code> keys. + * + * @author Juergen Hoeller + * @since 3.0 + */ +public class LinkedCaseInsensitiveMap<V> extends LinkedHashMap<String, V> { + + private final Map<String, String> caseInsensitiveKeys; + + private final Locale locale; + + + /** + * Create a new LinkedCaseInsensitiveMap for the default Locale. + * @see java.lang.String#toLowerCase() + */ + public LinkedCaseInsensitiveMap() { + this(null); + } + + /** + * Create a new LinkedCaseInsensitiveMap that stores lower-case keys + * according to the given Locale. + * @param locale the Locale to use for lower-case conversion + * @see java.lang.String#toLowerCase(java.util.Locale) + */ + public LinkedCaseInsensitiveMap(Locale locale) { + super(); + this.caseInsensitiveKeys = new HashMap<String, String>(); + this.locale = (locale != null ? locale : Locale.getDefault()); + } + + /** + * Create a new LinkedCaseInsensitiveMap that wraps a {@link LinkedHashMap} + * with the given initial capacity and stores lower-case keys according + * to the default Locale. + * @param initialCapacity the initial capacity + * @see java.lang.String#toLowerCase() + */ + public LinkedCaseInsensitiveMap(int initialCapacity) { + this(initialCapacity, null); + } + + /** + * Create a new LinkedCaseInsensitiveMap that wraps a {@link LinkedHashMap} + * with the given initial capacity and stores lower-case keys according + * to the given Locale. + * @param initialCapacity the initial capacity + * @param locale the Locale to use for lower-case conversion + * @see java.lang.String#toLowerCase(java.util.Locale) + */ + public LinkedCaseInsensitiveMap(int initialCapacity, Locale locale) { + super(initialCapacity); + this.caseInsensitiveKeys = new HashMap<String, String>(initialCapacity); + this.locale = (locale != null ? locale : Locale.getDefault()); + } + + + @Override + public V put(String key, V value) { + this.caseInsensitiveKeys.put(convertKey(key), key); + return super.put(key, value); + } + + @Override + public void putAll(Map<? extends String, ? extends V> map) { + if (map.isEmpty()) { + return; + } + for (Map.Entry<? extends String, ? extends V> entry : map.entrySet()) { + put(entry.getKey(), entry.getValue()); + } + } + + @Override + public boolean containsKey(Object key) { + return (key instanceof String && this.caseInsensitiveKeys.containsKey(convertKey((String) key))); + } + + @Override + public V get(Object key) { + if (key instanceof String) { + return super.get(this.caseInsensitiveKeys.get(convertKey((String) key))); + } + else { + return null; + } + } + + @Override + public V remove(Object key) { + if (key instanceof String ) { + return super.remove(this.caseInsensitiveKeys.remove(convertKey((String) key))); + } + else { + return null; + } + } + + @Override + public void clear() { + this.caseInsensitiveKeys.clear(); + super.clear(); + } + + + /** + * Convert the given key to a case-insensitive key. + * <p>The default implementation converts the key + * to lower-case according to this Map's Locale. + * @param key the user-specified key + * @return the key to use for storing + * @see java.lang.String#toLowerCase(java.util.Locale) + */ + protected String convertKey(String key) { + return key.toLowerCase(this.locale); + } + +} diff --git a/org.springframework.core/src/test/java/org/springframework/core/ExceptionDepthComparatorTests.java b/org.springframework.core/src/test/java/org/springframework/core/ExceptionDepthComparatorTests.java index 33176f71144..0e18a067db0 100644 --- a/org.springframework.core/src/test/java/org/springframework/core/ExceptionDepthComparatorTests.java +++ b/org.springframework.core/src/test/java/org/springframework/core/ExceptionDepthComparatorTests.java @@ -1,105 +1,105 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.core; - -import java.util.Arrays; - -import org.junit.Test; - -import static org.junit.Assert.*; - -/** - * @author Juergen Hoeller - * @author Chris Shepperd - */ -public class ExceptionDepthComparatorTests { - - @Test - public void targetBeforeSameDepth() throws Exception { - Class<? extends Throwable> foundClass = findClosestMatch(TargetException.class, SameDepthException.class); - assertEquals(TargetException.class, foundClass); - } - - @Test - public void sameDepthBeforeTarget() throws Exception { - Class<? extends Throwable> foundClass = findClosestMatch(SameDepthException.class, TargetException.class); - assertEquals(TargetException.class, foundClass); - } - - @Test - public void lowestDepthBeforeTarget() throws Exception { - Class<? extends Throwable> foundClass = findClosestMatch(LowestDepthException.class, TargetException.class); - assertEquals(TargetException.class, foundClass); - } - - @Test - public void targetBeforeLowestDepth() throws Exception { - Class<? extends Throwable> foundClass = findClosestMatch(TargetException.class, LowestDepthException.class); - assertEquals(TargetException.class, foundClass); - } - - @Test - public void noDepthBeforeTarget() throws Exception { - Class<? extends Throwable> foundClass = findClosestMatch(NoDepthException.class, TargetException.class); - assertEquals(TargetException.class, foundClass); - } - - @Test - public void noDepthBeforeHighestDepth() throws Exception { - Class<? extends Throwable> foundClass = findClosestMatch(NoDepthException.class, HighestDepthException.class); - assertEquals(HighestDepthException.class, foundClass); - } - - @Test - public void highestDepthBeforeNoDepth() throws Exception { - Class<? extends Throwable> foundClass = findClosestMatch(HighestDepthException.class, NoDepthException.class); - assertEquals(HighestDepthException.class, foundClass); - } - - @Test - public void highestDepthBeforeLowestDepth() throws Exception { - Class<? extends Throwable> foundClass = findClosestMatch(HighestDepthException.class, LowestDepthException.class); - assertEquals(LowestDepthException.class, foundClass); - } - - @Test - public void lowestDepthBeforeHighestDepth() throws Exception { - Class<? extends Throwable> foundClass = findClosestMatch(LowestDepthException.class, HighestDepthException.class); - assertEquals(LowestDepthException.class, foundClass); - } - - private Class<? extends Throwable> findClosestMatch(Class<? extends Throwable>... classes) { - return ExceptionDepthComparator.findClosestMatch(Arrays.asList(classes), new TargetException()); - } - - - public class HighestDepthException extends Throwable { - } - - public class LowestDepthException extends HighestDepthException { - } - - public class TargetException extends LowestDepthException { - } - - public class SameDepthException extends LowestDepthException { - } - - public class NoDepthException extends TargetException { - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.core; + +import java.util.Arrays; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * @author Juergen Hoeller + * @author Chris Shepperd + */ +public class ExceptionDepthComparatorTests { + + @Test + public void targetBeforeSameDepth() throws Exception { + Class<? extends Throwable> foundClass = findClosestMatch(TargetException.class, SameDepthException.class); + assertEquals(TargetException.class, foundClass); + } + + @Test + public void sameDepthBeforeTarget() throws Exception { + Class<? extends Throwable> foundClass = findClosestMatch(SameDepthException.class, TargetException.class); + assertEquals(TargetException.class, foundClass); + } + + @Test + public void lowestDepthBeforeTarget() throws Exception { + Class<? extends Throwable> foundClass = findClosestMatch(LowestDepthException.class, TargetException.class); + assertEquals(TargetException.class, foundClass); + } + + @Test + public void targetBeforeLowestDepth() throws Exception { + Class<? extends Throwable> foundClass = findClosestMatch(TargetException.class, LowestDepthException.class); + assertEquals(TargetException.class, foundClass); + } + + @Test + public void noDepthBeforeTarget() throws Exception { + Class<? extends Throwable> foundClass = findClosestMatch(NoDepthException.class, TargetException.class); + assertEquals(TargetException.class, foundClass); + } + + @Test + public void noDepthBeforeHighestDepth() throws Exception { + Class<? extends Throwable> foundClass = findClosestMatch(NoDepthException.class, HighestDepthException.class); + assertEquals(HighestDepthException.class, foundClass); + } + + @Test + public void highestDepthBeforeNoDepth() throws Exception { + Class<? extends Throwable> foundClass = findClosestMatch(HighestDepthException.class, NoDepthException.class); + assertEquals(HighestDepthException.class, foundClass); + } + + @Test + public void highestDepthBeforeLowestDepth() throws Exception { + Class<? extends Throwable> foundClass = findClosestMatch(HighestDepthException.class, LowestDepthException.class); + assertEquals(LowestDepthException.class, foundClass); + } + + @Test + public void lowestDepthBeforeHighestDepth() throws Exception { + Class<? extends Throwable> foundClass = findClosestMatch(LowestDepthException.class, HighestDepthException.class); + assertEquals(LowestDepthException.class, foundClass); + } + + private Class<? extends Throwable> findClosestMatch(Class<? extends Throwable>... classes) { + return ExceptionDepthComparator.findClosestMatch(Arrays.asList(classes), new TargetException()); + } + + + public class HighestDepthException extends Throwable { + } + + public class LowestDepthException extends HighestDepthException { + } + + public class TargetException extends LowestDepthException { + } + + public class SameDepthException extends LowestDepthException { + } + + public class NoDepthException extends TargetException { + } + +} diff --git a/org.springframework.core/src/test/java/org/springframework/core/GenericTypeResolverTests.java b/org.springframework.core/src/test/java/org/springframework/core/GenericTypeResolverTests.java index c1568ff8cda..5514e0376c5 100644 --- a/org.springframework.core/src/test/java/org/springframework/core/GenericTypeResolverTests.java +++ b/org.springframework.core/src/test/java/org/springframework/core/GenericTypeResolverTests.java @@ -1,97 +1,97 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.core; - -import java.util.Collection; - -import org.junit.Test; - -import org.springframework.util.ReflectionUtils; - -import static org.junit.Assert.*; - -/** - * @author Juergen Hoeller - */ -public class GenericTypeResolverTests { - - @Test - public void testSimpleInterfaceType() { - assertEquals(String.class, GenericTypeResolver.resolveTypeArgument(MySimpleInterfaceType.class, MyInterfaceType.class)); - } - - @Test - public void testSimpleCollectionInterfaceType() { - assertEquals(Collection.class, GenericTypeResolver.resolveTypeArgument(MyCollectionInterfaceType.class, MyInterfaceType.class)); - } - - @Test - public void testSimpleSuperclassType() { - assertEquals(String.class, GenericTypeResolver.resolveTypeArgument(MySimpleSuperclassType.class, MySuperclassType.class)); - } - - @Test - public void testSimpleCollectionSuperclassType() { - assertEquals(Collection.class, GenericTypeResolver.resolveTypeArgument(MyCollectionSuperclassType.class, MySuperclassType.class)); - } - - @Test - public void testMethodReturnType() { - assertEquals(Integer.class, GenericTypeResolver.resolveReturnTypeArgument(ReflectionUtils.findMethod(MyTypeWithMethods.class, "integer"), MyInterfaceType.class)); - assertEquals(String.class, GenericTypeResolver.resolveReturnTypeArgument(ReflectionUtils.findMethod(MyTypeWithMethods.class, "string"), MyInterfaceType.class)); - assertEquals(null, GenericTypeResolver.resolveReturnTypeArgument(ReflectionUtils.findMethod(MyTypeWithMethods.class, "raw"), MyInterfaceType.class)); - assertEquals(null, GenericTypeResolver.resolveReturnTypeArgument(ReflectionUtils.findMethod(MyTypeWithMethods.class, "object"), MyInterfaceType.class)); - } - - @Test - public void testNullIfNotResolvable() { - GenericClass<String> obj = new GenericClass<String>(); - assertNull(GenericTypeResolver.resolveTypeArgument(obj.getClass(), GenericClass.class)); - } - - - public interface MyInterfaceType<T> { - } - - public class MySimpleInterfaceType implements MyInterfaceType<String> { - } - - public class MyCollectionInterfaceType implements MyInterfaceType<Collection<String>> { - } - - - public abstract class MySuperclassType<T> { - } - - public class MySimpleSuperclassType extends MySuperclassType<String> { - } - - public class MyCollectionSuperclassType extends MySuperclassType<Collection<String>> { - } - - public class MyTypeWithMethods { - public MyInterfaceType<Integer> integer() { return null; } - public MySimpleInterfaceType string() { return null; } - public Object object() { return null; } - @SuppressWarnings("rawtypes") - public MyInterfaceType raw() { return null; } - } - - static class GenericClass<T> { - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.core; + +import java.util.Collection; + +import org.junit.Test; + +import org.springframework.util.ReflectionUtils; + +import static org.junit.Assert.*; + +/** + * @author Juergen Hoeller + */ +public class GenericTypeResolverTests { + + @Test + public void testSimpleInterfaceType() { + assertEquals(String.class, GenericTypeResolver.resolveTypeArgument(MySimpleInterfaceType.class, MyInterfaceType.class)); + } + + @Test + public void testSimpleCollectionInterfaceType() { + assertEquals(Collection.class, GenericTypeResolver.resolveTypeArgument(MyCollectionInterfaceType.class, MyInterfaceType.class)); + } + + @Test + public void testSimpleSuperclassType() { + assertEquals(String.class, GenericTypeResolver.resolveTypeArgument(MySimpleSuperclassType.class, MySuperclassType.class)); + } + + @Test + public void testSimpleCollectionSuperclassType() { + assertEquals(Collection.class, GenericTypeResolver.resolveTypeArgument(MyCollectionSuperclassType.class, MySuperclassType.class)); + } + + @Test + public void testMethodReturnType() { + assertEquals(Integer.class, GenericTypeResolver.resolveReturnTypeArgument(ReflectionUtils.findMethod(MyTypeWithMethods.class, "integer"), MyInterfaceType.class)); + assertEquals(String.class, GenericTypeResolver.resolveReturnTypeArgument(ReflectionUtils.findMethod(MyTypeWithMethods.class, "string"), MyInterfaceType.class)); + assertEquals(null, GenericTypeResolver.resolveReturnTypeArgument(ReflectionUtils.findMethod(MyTypeWithMethods.class, "raw"), MyInterfaceType.class)); + assertEquals(null, GenericTypeResolver.resolveReturnTypeArgument(ReflectionUtils.findMethod(MyTypeWithMethods.class, "object"), MyInterfaceType.class)); + } + + @Test + public void testNullIfNotResolvable() { + GenericClass<String> obj = new GenericClass<String>(); + assertNull(GenericTypeResolver.resolveTypeArgument(obj.getClass(), GenericClass.class)); + } + + + public interface MyInterfaceType<T> { + } + + public class MySimpleInterfaceType implements MyInterfaceType<String> { + } + + public class MyCollectionInterfaceType implements MyInterfaceType<Collection<String>> { + } + + + public abstract class MySuperclassType<T> { + } + + public class MySimpleSuperclassType extends MySuperclassType<String> { + } + + public class MyCollectionSuperclassType extends MySuperclassType<Collection<String>> { + } + + public class MyTypeWithMethods { + public MyInterfaceType<Integer> integer() { return null; } + public MySimpleInterfaceType string() { return null; } + public Object object() { return null; } + @SuppressWarnings("rawtypes") + public MyInterfaceType raw() { return null; } + } + + static class GenericClass<T> { + } + +} diff --git a/org.springframework.core/src/test/java/org/springframework/core/convert/TypeDescriptorTests.java b/org.springframework.core/src/test/java/org/springframework/core/convert/TypeDescriptorTests.java index 4e5dd880ea5..5241788c3aa 100644 --- a/org.springframework.core/src/test/java/org/springframework/core/convert/TypeDescriptorTests.java +++ b/org.springframework.core/src/test/java/org/springframework/core/convert/TypeDescriptorTests.java @@ -1,801 +1,801 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.core.convert; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.junit.Test; - -import org.springframework.core.MethodParameter; - -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertTrue; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; - -/** - * @author Keith Donald - * @author Andy Clement - */ -@SuppressWarnings("rawtypes") -public class TypeDescriptorTests { - - public List<String> listOfString; - - public List<List<String>> listOfListOfString = new ArrayList<List<String>>(); - - public List<List> listOfListOfUnknown = new ArrayList<List>(); - - public int[] intArray; - - public List<String>[] arrayOfListOfString; - - public List<Integer> listField = new ArrayList<Integer>(); - - public Map<String, Integer> mapField = new HashMap<String, Integer>(); - - public Map<String, List<Integer>> nestedMapField = new HashMap<String, List<Integer>>(); - - @Test - public void parameterPrimitive() throws Exception { - TypeDescriptor desc = new TypeDescriptor(new MethodParameter(getClass().getMethod("testParameterPrimitive", int.class), 0)); - assertEquals(int.class, desc.getType()); - assertEquals(Integer.class, desc.getObjectType()); - assertEquals("int", desc.getName()); - assertEquals("int", desc.toString()); - assertTrue(desc.isPrimitive()); - assertEquals(0, desc.getAnnotations().length); - assertFalse(desc.isCollection()); - assertFalse(desc.isMap()); - } - - public void testParameterPrimitive(int primitive) { - - } - - @Test - public void parameterScalar() throws Exception { - TypeDescriptor desc = new TypeDescriptor(new MethodParameter(getClass().getMethod("testParameterScalar", String.class), 0)); - assertEquals(String.class, desc.getType()); - assertEquals(String.class, desc.getObjectType()); - assertEquals("java.lang.String", desc.getName()); - assertEquals("java.lang.String", desc.toString()); - assertTrue(!desc.isPrimitive()); - assertEquals(0, desc.getAnnotations().length); - assertFalse(desc.isCollection()); - assertFalse(desc.isArray()); - assertFalse(desc.isMap()); - } - - public void testParameterScalar(String value) { - - } - - @Test - public void parameterList() throws Exception { - MethodParameter methodParameter = new MethodParameter(getClass().getMethod("testParameterList", List.class), 0); - TypeDescriptor desc = new TypeDescriptor(methodParameter); - assertEquals(List.class, desc.getType()); - assertEquals(List.class, desc.getObjectType()); - assertEquals("java.util.List", desc.getName()); - assertEquals("java.util.List<java.util.List<java.util.Map<java.lang.Integer, java.lang.Enum>>>", desc.toString()); - assertTrue(!desc.isPrimitive()); - assertEquals(0, desc.getAnnotations().length); - assertTrue(desc.isCollection()); - assertFalse(desc.isArray()); - assertEquals(List.class, desc.getElementTypeDescriptor().getType()); - assertEquals(TypeDescriptor.nested(methodParameter, 1), desc.getElementTypeDescriptor()); - assertEquals(TypeDescriptor.nested(methodParameter, 2), desc.getElementTypeDescriptor().getElementTypeDescriptor()); - assertEquals(TypeDescriptor.nested(methodParameter, 3), desc.getElementTypeDescriptor().getElementTypeDescriptor().getMapValueTypeDescriptor()); - assertEquals(Integer.class, desc.getElementTypeDescriptor().getElementTypeDescriptor().getMapKeyTypeDescriptor().getType()); - assertEquals(Enum.class, desc.getElementTypeDescriptor().getElementTypeDescriptor().getMapValueTypeDescriptor().getType()); - assertFalse(desc.isMap()); - } - - public void testParameterList(List<List<Map<Integer, Enum<?>>>> list) { - - } - - @Test - public void parameterListNoParamTypes() throws Exception { - MethodParameter methodParameter = new MethodParameter(getClass().getMethod("testParameterListNoParamTypes", List.class), 0); - TypeDescriptor desc = new TypeDescriptor(methodParameter); - assertEquals(List.class, desc.getType()); - assertEquals(List.class, desc.getObjectType()); - assertEquals("java.util.List", desc.getName()); - assertEquals("java.util.List<?>", desc.toString()); - assertTrue(!desc.isPrimitive()); - assertEquals(0, desc.getAnnotations().length); - assertTrue(desc.isCollection()); - assertFalse(desc.isArray()); - assertNull(desc.getElementTypeDescriptor()); - assertFalse(desc.isMap()); - } - - public void testParameterListNoParamTypes(List list) { - - } - - @Test - public void parameterArray() throws Exception { - MethodParameter methodParameter = new MethodParameter(getClass().getMethod("testParameterArray", Integer[].class), 0); - TypeDescriptor desc = new TypeDescriptor(methodParameter); - assertEquals(Integer[].class, desc.getType()); - assertEquals(Integer[].class, desc.getObjectType()); - assertEquals("java.lang.Integer[]", desc.getName()); - assertEquals("java.lang.Integer[]", desc.toString()); - assertTrue(!desc.isPrimitive()); - assertEquals(0, desc.getAnnotations().length); - assertFalse(desc.isCollection()); - assertTrue(desc.isArray()); - assertEquals(Integer.class, desc.getElementTypeDescriptor().getType()); - assertEquals(TypeDescriptor.valueOf(Integer.class), desc.getElementTypeDescriptor()); - assertFalse(desc.isMap()); - } - - public void testParameterArray(Integer[] array) { - - } - - @Test - public void parameterMap() throws Exception { - MethodParameter methodParameter = new MethodParameter(getClass().getMethod("testParameterMap", Map.class), 0); - TypeDescriptor desc = new TypeDescriptor(methodParameter); - assertEquals(Map.class, desc.getType()); - assertEquals(Map.class, desc.getObjectType()); - assertEquals("java.util.Map", desc.getName()); - assertEquals("java.util.Map<java.lang.Integer, java.util.List<java.lang.String>>", desc.toString()); - assertTrue(!desc.isPrimitive()); - assertEquals(0, desc.getAnnotations().length); - assertFalse(desc.isCollection()); - assertFalse(desc.isArray()); - assertTrue(desc.isMap()); - assertEquals(TypeDescriptor.nested(methodParameter, 1), desc.getMapValueTypeDescriptor()); - assertEquals(TypeDescriptor.nested(methodParameter, 2), desc.getMapValueTypeDescriptor().getElementTypeDescriptor()); - assertEquals(Integer.class, desc.getMapKeyTypeDescriptor().getType()); - assertEquals(List.class, desc.getMapValueTypeDescriptor().getType()); - assertEquals(String.class, desc.getMapValueTypeDescriptor().getElementTypeDescriptor().getType()); - } - - public void testParameterMap(Map<Integer, List<String>> map) { - - } - - @Test - public void parameterAnnotated() throws Exception { - TypeDescriptor t1 = new TypeDescriptor(new MethodParameter(getClass().getMethod("testAnnotatedMethod", String.class), 0)); - assertEquals(String.class, t1.getType()); - assertEquals(1, t1.getAnnotations().length); - assertNotNull(t1.getAnnotation(ParameterAnnotation.class)); - } - - @Target({ElementType.PARAMETER}) - @Retention(RetentionPolicy.RUNTIME) - public @interface ParameterAnnotation { - - } - - public void testAnnotatedMethod(@ParameterAnnotation String parameter) { - - } - - @Test - public void propertyComplex() throws Exception { - Property property = new Property(getClass(), getClass().getMethod("getComplexProperty"), getClass().getMethod("setComplexProperty", Map.class)); - TypeDescriptor desc = new TypeDescriptor(property); - assertEquals(String.class, desc.getMapKeyTypeDescriptor().getType()); - assertEquals(Integer.class, desc.getMapValueTypeDescriptor().getElementTypeDescriptor().getElementTypeDescriptor().getType()); - } - - public Map<String, List<List<Integer>>> getComplexProperty() { - return null; - } - - public void setComplexProperty(Map<String, List<List<Integer>>> complexProperty) { - - } - - @Test - public void propertyGenericType() throws Exception { - GenericType<Integer> genericBean = new IntegerType(); - Property property = new Property(getClass(), genericBean.getClass().getMethod("getProperty"), genericBean.getClass().getMethod("setProperty", Integer.class)); - TypeDescriptor desc = new TypeDescriptor(property); - assertEquals(Integer.class, desc.getType()); - } - - @Test - public void propertyTypeCovariance() throws Exception { - GenericType<Number> genericBean = new NumberType(); - Property property = new Property(getClass(), genericBean.getClass().getMethod("getProperty"), genericBean.getClass().getMethod("setProperty", Number.class)); - TypeDescriptor desc = new TypeDescriptor(property); - assertEquals(Integer.class, desc.getType()); - } - - @Test - public void propertyGenericTypeList() throws Exception { - GenericType<Integer> genericBean = new IntegerType(); - Property property = new Property(getClass(), genericBean.getClass().getMethod("getListProperty"), genericBean.getClass().getMethod("setListProperty", List.class)); - TypeDescriptor desc = new TypeDescriptor(property); - assertEquals(List.class, desc.getType()); - assertEquals(Integer.class, desc.getElementTypeDescriptor().getType()); - } - - public interface GenericType<T> { - T getProperty(); - - void setProperty(T t); - - List<T> getListProperty(); - - void setListProperty(List<T> t); - - } - - public class IntegerType implements GenericType<Integer> { - - public Integer getProperty() { - return null; - } - - public void setProperty(Integer t) { - } - - public List<Integer> getListProperty() { - return null; - } - - public void setListProperty(List<Integer> t) { - } - } - - public class NumberType implements GenericType<Number> { - - public Integer getProperty() { - return null; - } - - public void setProperty(Number t) { - } - - public List<Number> getListProperty() { - return null; - } - - public void setListProperty(List<Number> t) { - } - } - - @Test - public void propertyGenericClassList() throws Exception { - IntegerClass genericBean = new IntegerClass(); - Property property = new Property(genericBean.getClass(), genericBean.getClass().getMethod("getListProperty"), genericBean.getClass().getMethod("setListProperty", List.class)); - TypeDescriptor desc = new TypeDescriptor(property); - assertEquals(List.class, desc.getType()); - assertEquals(Integer.class, desc.getElementTypeDescriptor().getType()); - assertNotNull(desc.getAnnotation(MethodAnnotation1.class)); - } - - public static class GenericClass<T> { - - public T getProperty() { - return null; - } - - public void setProperty(T t) { - } - - @MethodAnnotation1 - public List<T> getListProperty() { - return null; - } - - public void setListProperty(List<T> t) { - } - - } - - public static class IntegerClass extends GenericClass<Integer> { - - } - - @Test - public void property() throws Exception { - Property property = new Property(getClass(), getClass().getMethod("getProperty"), getClass().getMethod("setProperty", Map.class)); - TypeDescriptor desc = new TypeDescriptor(property); - assertEquals(Map.class, desc.getType()); - assertEquals(Integer.class, desc.getMapKeyTypeDescriptor().getElementTypeDescriptor().getType()); - assertEquals(Long.class, desc.getMapValueTypeDescriptor().getElementTypeDescriptor().getType()); - assertNotNull(desc.getAnnotation(MethodAnnotation1.class)); - assertNotNull(desc.getAnnotation(MethodAnnotation2.class)); - assertNotNull(desc.getAnnotation(MethodAnnotation3.class)); - } - - @MethodAnnotation1 - public Map<List<Integer>, List<Long>> getProperty() { - return property; - } - - @MethodAnnotation2 - public void setProperty(Map<List<Integer>, List<Long>> property) { - this.property = property; - } - - @MethodAnnotation3 - private Map<List<Integer>, List<Long>> property; - - @Target({ElementType.METHOD}) - @Retention(RetentionPolicy.RUNTIME) - public @interface MethodAnnotation1 { - - } - - @Target({ElementType.METHOD}) - @Retention(RetentionPolicy.RUNTIME) - public @interface MethodAnnotation2 { - - } - - @Target({ElementType.FIELD}) - @Retention(RetentionPolicy.RUNTIME) - public @interface MethodAnnotation3 { - - } - - @Test - public void fieldScalar() throws Exception { - TypeDescriptor typeDescriptor = new TypeDescriptor(getClass().getField("fieldScalar")); - assertFalse(typeDescriptor.isPrimitive()); - assertFalse(typeDescriptor.isArray()); - assertFalse(typeDescriptor.isCollection()); - assertFalse(typeDescriptor.isMap()); - assertEquals(Integer.class, typeDescriptor.getType()); - assertEquals(Integer.class, typeDescriptor.getObjectType()); - } - - public Integer fieldScalar; - - @Test - public void fieldList() throws Exception { - TypeDescriptor typeDescriptor = new TypeDescriptor(TypeDescriptorTests.class.getDeclaredField("listOfString")); - assertFalse(typeDescriptor.isArray()); - assertEquals(List.class, typeDescriptor.getType()); - assertEquals(String.class, typeDescriptor.getElementTypeDescriptor().getType()); - assertEquals("java.util.List<java.lang.String>", typeDescriptor.toString()); - } - - @Test - public void fieldListOfListOfString() throws Exception { - TypeDescriptor typeDescriptor = new TypeDescriptor(TypeDescriptorTests.class.getDeclaredField("listOfListOfString")); - assertFalse(typeDescriptor.isArray()); - assertEquals(List.class, typeDescriptor.getType()); - assertEquals(List.class, typeDescriptor.getElementTypeDescriptor().getType()); - assertEquals(String.class, typeDescriptor.getElementTypeDescriptor().getElementTypeDescriptor().getType()); - assertEquals("java.util.List<java.util.List<java.lang.String>>", typeDescriptor.toString()); - } - - @Test - public void fieldListOfListUnknown() throws Exception { - TypeDescriptor typeDescriptor = new TypeDescriptor(TypeDescriptorTests.class.getDeclaredField("listOfListOfUnknown")); - assertFalse(typeDescriptor.isArray()); - assertEquals(List.class, typeDescriptor.getType()); - assertEquals(List.class, typeDescriptor.getElementTypeDescriptor().getType()); - assertNull(typeDescriptor.getElementTypeDescriptor().getElementTypeDescriptor()); - assertEquals("java.util.List<java.util.List<?>>", typeDescriptor.toString()); - } - - @Test - public void fieldArray() throws Exception { - TypeDescriptor typeDescriptor = new TypeDescriptor(TypeDescriptorTests.class.getDeclaredField("intArray")); - assertTrue(typeDescriptor.isArray()); - assertEquals(Integer.TYPE,typeDescriptor.getElementTypeDescriptor().getType()); - assertEquals("int[]",typeDescriptor.toString()); - } - - @Test - public void fieldComplexTypeDescriptor() throws Exception { - TypeDescriptor typeDescriptor = new TypeDescriptor(TypeDescriptorTests.class.getDeclaredField("arrayOfListOfString")); - assertTrue(typeDescriptor.isArray()); - assertEquals(List.class,typeDescriptor.getElementTypeDescriptor().getType()); - assertEquals(String.class, typeDescriptor.getElementTypeDescriptor().getElementTypeDescriptor().getType()); - assertEquals("java.util.List[]",typeDescriptor.toString()); - } - - @Test - public void fieldComplexTypeDescriptor2() throws Exception { - TypeDescriptor typeDescriptor = new TypeDescriptor(TypeDescriptorTests.class.getDeclaredField("nestedMapField")); - assertTrue(typeDescriptor.isMap()); - assertEquals(String.class,typeDescriptor.getMapKeyTypeDescriptor().getType()); - assertEquals(List.class, typeDescriptor.getMapValueTypeDescriptor().getType()); - assertEquals(Integer.class, typeDescriptor.getMapValueTypeDescriptor().getElementTypeDescriptor().getType()); - assertEquals("java.util.Map<java.lang.String, java.util.List<java.lang.Integer>>", typeDescriptor.toString()); - } - - @Test - public void fieldMap() throws Exception { - TypeDescriptor desc = new TypeDescriptor(TypeDescriptorTests.class.getField("fieldMap")); - assertTrue(desc.isMap()); - assertEquals(Integer.class, desc.getMapKeyTypeDescriptor().getElementTypeDescriptor().getType()); - assertEquals(Long.class, desc.getMapValueTypeDescriptor().getElementTypeDescriptor().getType()); - } - - public Map<List<Integer>, List<Long>> fieldMap; - - @Test - public void fieldAnnotated() throws Exception { - TypeDescriptor typeDescriptor = new TypeDescriptor(getClass().getField("fieldAnnotated")); - assertEquals(1, typeDescriptor.getAnnotations().length); - assertNotNull(typeDescriptor.getAnnotation(FieldAnnotation.class)); - } - - @FieldAnnotation - public List<String> fieldAnnotated; - - @Target({ElementType.FIELD}) - @Retention(RetentionPolicy.RUNTIME) - public @interface FieldAnnotation { - - } - - @Test - public void valueOfScalar() { - TypeDescriptor typeDescriptor = TypeDescriptor.valueOf(Integer.class); - assertFalse(typeDescriptor.isPrimitive()); - assertFalse(typeDescriptor.isArray()); - assertFalse(typeDescriptor.isCollection()); - assertFalse(typeDescriptor.isMap()); - assertEquals(Integer.class, typeDescriptor.getType()); - assertEquals(Integer.class, typeDescriptor.getObjectType()); - } - - @Test - public void valueOfPrimitive() { - TypeDescriptor typeDescriptor = TypeDescriptor.valueOf(int.class); - assertTrue(typeDescriptor.isPrimitive()); - assertFalse(typeDescriptor.isArray()); - assertFalse(typeDescriptor.isCollection()); - assertFalse(typeDescriptor.isMap()); - assertEquals(Integer.TYPE, typeDescriptor.getType()); - assertEquals(Integer.class, typeDescriptor.getObjectType()); - } - - @Test - public void valueOfArray() throws Exception { - TypeDescriptor typeDescriptor = TypeDescriptor.valueOf(int[].class); - assertTrue(typeDescriptor.isArray()); - assertFalse(typeDescriptor.isCollection()); - assertFalse(typeDescriptor.isMap()); - assertEquals(Integer.TYPE, typeDescriptor.getElementTypeDescriptor().getType()); - } - - @Test - public void valueOfCollection() throws Exception { - TypeDescriptor typeDescriptor = TypeDescriptor.valueOf(Collection.class); - assertTrue(typeDescriptor.isCollection()); - assertFalse(typeDescriptor.isArray()); - assertFalse(typeDescriptor.isMap()); - assertNull(typeDescriptor.getElementTypeDescriptor()); - } - - @Test - public void forObject() { - TypeDescriptor desc = TypeDescriptor.forObject("3"); - assertEquals(String.class, desc.getType()); - } - - @Test - public void forObjectNullTypeDescriptor() { - TypeDescriptor desc = TypeDescriptor.forObject(null); - assertNull(desc); - } - - @Test - public void nestedMethodParameterType2Levels() throws Exception { - TypeDescriptor t1 = TypeDescriptor.nested(new MethodParameter(getClass().getMethod("test2", List.class), 0), 2); - assertEquals(String.class, t1.getType()); - } - - @Test - public void nestedMethodParameterTypeMap() throws Exception { - TypeDescriptor t1 = TypeDescriptor.nested(new MethodParameter(getClass().getMethod("test3", Map.class), 0), 1); - assertEquals(String.class, t1.getType()); - } - - @Test - public void nestedMethodParameterTypeMapTwoLevels() throws Exception { - TypeDescriptor t1 = TypeDescriptor.nested(new MethodParameter(getClass().getMethod("test4", List.class), 0), 2); - assertEquals(String.class, t1.getType()); - } - - @Test(expected=IllegalArgumentException.class) - public void nestedMethodParameterNot1NestedLevel() throws Exception { - TypeDescriptor.nested(new MethodParameter(getClass().getMethod("test4", List.class), 0, 2), 2); - } - - @Test(expected=IllegalStateException.class) - public void nestedTooManyLevels() throws Exception { - TypeDescriptor t1 = TypeDescriptor.nested(new MethodParameter(getClass().getMethod("test4", List.class), 0), 3); - assertEquals(String.class, t1.getType()); - } - - @Test(expected=IllegalStateException.class) - public void nestedMethodParameterTypeNotNestable() throws Exception { - TypeDescriptor.nested(new MethodParameter(getClass().getMethod("test5", String.class), 0), 2); - } - - @Test(expected=IllegalArgumentException.class) - public void nestedMethodParameterTypeInvalidNestingLevel() throws Exception { - TypeDescriptor.nested(new MethodParameter(getClass().getMethod("test5", String.class), 0, 2), 2); - } - - public void test1(List<String> param1) { - - } - - public void test2(List<List<String>> param1) { - - } - - public void test3(Map<Integer, String> param1) { - - } - - public void test4(List<Map<Integer, String>> param1) { - - } - - public void test5(String param1) { - - } - - @Test - public void nestedNotParameterized() throws Exception { - TypeDescriptor t1 = TypeDescriptor.nested(new MethodParameter(getClass().getMethod("test6", List.class), 0), 1); - assertEquals(List.class,t1.getType()); - assertEquals("java.util.List<?>", t1.toString()); - TypeDescriptor t2 = TypeDescriptor.nested(new MethodParameter(getClass().getMethod("test6", List.class), 0), 2); - assertNull(t2); - } - - public void test6(List<List> param1) { - - } - - @Test - public void nestedFieldTypeMapTwoLevels() throws Exception { - TypeDescriptor t1 = TypeDescriptor.nested(getClass().getField("test4"), 2); - assertEquals(String.class, t1.getType()); - } - - public List<Map<Integer, String>> test4; - - @Test - public void nestedPropertyTypeMapTwoLevels() throws Exception { - Property property = new Property(getClass(), getClass().getMethod("getTest4"), getClass().getMethod("setTest4", List.class)); - TypeDescriptor t1 = TypeDescriptor.nested(property, 2); - assertEquals(String.class, t1.getType()); - } - - public List<Map<Integer, String>> getTest4() { - return null; - } - - public void setTest4(List<Map<Integer, String>> test4) { - - } - - @Test - public void collection() { - TypeDescriptor desc = TypeDescriptor.collection(List.class, TypeDescriptor.valueOf(Integer.class)); - assertEquals(List.class, desc.getType()); - assertEquals(List.class, desc.getObjectType()); - assertEquals("java.util.List", desc.getName()); - assertEquals("java.util.List<java.lang.Integer>", desc.toString()); - assertTrue(!desc.isPrimitive()); - assertEquals(0, desc.getAnnotations().length); - assertTrue(desc.isCollection()); - assertFalse(desc.isArray()); - assertEquals(Integer.class, desc.getElementTypeDescriptor().getType()); - assertEquals(TypeDescriptor.valueOf(Integer.class), desc.getElementTypeDescriptor()); - assertFalse(desc.isMap()); - } - - @Test - public void collectionNested() { - TypeDescriptor desc = TypeDescriptor.collection(List.class, TypeDescriptor.collection(List.class, TypeDescriptor.valueOf(Integer.class))); - assertEquals(List.class, desc.getType()); - assertEquals(List.class, desc.getObjectType()); - assertEquals("java.util.List", desc.getName()); - assertEquals("java.util.List<java.util.List<java.lang.Integer>>", desc.toString()); - assertTrue(!desc.isPrimitive()); - assertEquals(0, desc.getAnnotations().length); - assertTrue(desc.isCollection()); - assertFalse(desc.isArray()); - assertEquals(List.class, desc.getElementTypeDescriptor().getType()); - assertEquals(TypeDescriptor.valueOf(Integer.class), desc.getElementTypeDescriptor().getElementTypeDescriptor()); - assertFalse(desc.isMap()); - } - - @Test - public void map() { - TypeDescriptor desc = TypeDescriptor.map(Map.class, TypeDescriptor.valueOf(String.class), TypeDescriptor.valueOf(Integer.class)); - assertEquals(Map.class, desc.getType()); - assertEquals(Map.class, desc.getObjectType()); - assertEquals("java.util.Map", desc.getName()); - assertEquals("java.util.Map<java.lang.String, java.lang.Integer>", desc.toString()); - assertTrue(!desc.isPrimitive()); - assertEquals(0, desc.getAnnotations().length); - assertFalse(desc.isCollection()); - assertFalse(desc.isArray()); - assertTrue(desc.isMap()); - assertEquals(String.class, desc.getMapKeyTypeDescriptor().getType()); - assertEquals(Integer.class, desc.getMapValueTypeDescriptor().getType()); - } - - @Test - public void mapNested() { - TypeDescriptor desc = TypeDescriptor.map(Map.class, TypeDescriptor.valueOf(String.class), - TypeDescriptor.map(Map.class, TypeDescriptor.valueOf(String.class), TypeDescriptor.valueOf(Integer.class))); - assertEquals(Map.class, desc.getType()); - assertEquals(Map.class, desc.getObjectType()); - assertEquals("java.util.Map", desc.getName()); - assertEquals("java.util.Map<java.lang.String, java.util.Map<java.lang.String, java.lang.Integer>>", desc.toString()); - assertTrue(!desc.isPrimitive()); - assertEquals(0, desc.getAnnotations().length); - assertFalse(desc.isCollection()); - assertFalse(desc.isArray()); - assertTrue(desc.isMap()); - assertEquals(String.class, desc.getMapKeyTypeDescriptor().getType()); - assertEquals(String.class, desc.getMapValueTypeDescriptor().getMapKeyTypeDescriptor().getType()); - assertEquals(Integer.class, desc.getMapValueTypeDescriptor().getMapValueTypeDescriptor().getType()); - } - - @Test - public void narrow() { - TypeDescriptor desc = TypeDescriptor.valueOf(Number.class); - Integer value = new Integer(3); - desc = desc.narrow(value); - assertEquals(Integer.class, desc.getType()); - } - - @Test - public void elementType() { - TypeDescriptor desc = TypeDescriptor.valueOf(List.class); - Integer value = new Integer(3); - desc = desc.elementTypeDescriptor(value); - assertEquals(Integer.class, desc.getType()); - } - - @Test - public void elementTypePreserveContext() throws Exception { - TypeDescriptor desc = new TypeDescriptor(getClass().getField("listPreserveContext")); - assertEquals(Integer.class, desc.getElementTypeDescriptor().getElementTypeDescriptor().getType()); - List<Integer> value = new ArrayList<Integer>(3); - desc = desc.elementTypeDescriptor(value); - assertEquals(Integer.class, desc.getElementTypeDescriptor().getType()); - assertNotNull(desc.getAnnotation(FieldAnnotation.class)); - } - - @FieldAnnotation - public List<List<Integer>> listPreserveContext; - - @Test - public void mapKeyType() { - TypeDescriptor desc = TypeDescriptor.valueOf(Map.class); - Integer value = new Integer(3); - desc = desc.getMapKeyTypeDescriptor(value); - assertEquals(Integer.class, desc.getType()); - } - - @Test - public void mapKeyTypePreserveContext() throws Exception { - TypeDescriptor desc = new TypeDescriptor(getClass().getField("mapPreserveContext")); - assertEquals(Integer.class, desc.getMapKeyTypeDescriptor().getElementTypeDescriptor().getType()); - List<Integer> value = new ArrayList<Integer>(3); - desc = desc.getMapKeyTypeDescriptor(value); - assertEquals(Integer.class, desc.getElementTypeDescriptor().getType()); - assertNotNull(desc.getAnnotation(FieldAnnotation.class)); - } - - @FieldAnnotation - public Map<List<Integer>, List<Integer>> mapPreserveContext; - - @Test - public void mapValueType() { - TypeDescriptor desc = TypeDescriptor.valueOf(Map.class); - Integer value = new Integer(3); - desc = desc.getMapValueTypeDescriptor(value); - assertEquals(Integer.class, desc.getType()); - } - - @Test - public void mapValueTypePreserveContext() throws Exception { - TypeDescriptor desc = new TypeDescriptor(getClass().getField("mapPreserveContext")); - assertEquals(Integer.class, desc.getMapValueTypeDescriptor().getElementTypeDescriptor().getType()); - List<Integer> value = new ArrayList<Integer>(3); - desc = desc.getMapValueTypeDescriptor(value); - assertEquals(Integer.class, desc.getElementTypeDescriptor().getType()); - assertNotNull(desc.getAnnotation(FieldAnnotation.class)); - } - - @Test - public void equals() throws Exception { - TypeDescriptor t1 = TypeDescriptor.valueOf(String.class); - TypeDescriptor t2 = TypeDescriptor.valueOf(String.class); - TypeDescriptor t3 = TypeDescriptor.valueOf(Date.class); - TypeDescriptor t4 = TypeDescriptor.valueOf(Date.class); - TypeDescriptor t5 = TypeDescriptor.valueOf(List.class); - TypeDescriptor t6 = TypeDescriptor.valueOf(List.class); - TypeDescriptor t7 = TypeDescriptor.valueOf(Map.class); - TypeDescriptor t8 = TypeDescriptor.valueOf(Map.class); - assertEquals(t1, t2); - assertEquals(t3, t4); - assertEquals(t5, t6); - assertEquals(t7, t8); - - TypeDescriptor t9 = new TypeDescriptor(getClass().getField("listField")); - TypeDescriptor t10 = new TypeDescriptor(getClass().getField("listField")); - assertEquals(t9, t10); - - TypeDescriptor t11 = new TypeDescriptor(getClass().getField("mapField")); - TypeDescriptor t12 = new TypeDescriptor(getClass().getField("mapField")); - assertEquals(t11, t12); - } - - @Test - public void isAssignableTypes() { - assertTrue(TypeDescriptor.valueOf(Integer.class).isAssignableTo(TypeDescriptor.valueOf(Number.class))); - assertFalse(TypeDescriptor.valueOf(Number.class).isAssignableTo(TypeDescriptor.valueOf(Integer.class))); - assertFalse(TypeDescriptor.valueOf(String.class).isAssignableTo(TypeDescriptor.valueOf(String[].class))); - } - - @Test - public void isAssignableElementTypes() throws Exception { - assertTrue(new TypeDescriptor(getClass().getField("listField")).isAssignableTo(new TypeDescriptor(getClass().getField("listField")))); - assertTrue(new TypeDescriptor(getClass().getField("notGenericList")).isAssignableTo(new TypeDescriptor(getClass().getField("listField")))); - assertTrue(new TypeDescriptor(getClass().getField("listField")).isAssignableTo(new TypeDescriptor(getClass().getField("notGenericList")))); - assertFalse(new TypeDescriptor(getClass().getField("isAssignableElementTypes")).isAssignableTo(new TypeDescriptor(getClass().getField("listField")))); - assertTrue(TypeDescriptor.valueOf(List.class).isAssignableTo(new TypeDescriptor(getClass().getField("listField")))); - } - - public List notGenericList; - - public List<Number> isAssignableElementTypes; - - @Test - public void isAssignableMapKeyValueTypes() throws Exception { - assertTrue(new TypeDescriptor(getClass().getField("mapField")).isAssignableTo(new TypeDescriptor(getClass().getField("mapField")))); - assertTrue(new TypeDescriptor(getClass().getField("notGenericMap")).isAssignableTo(new TypeDescriptor(getClass().getField("mapField")))); - assertTrue(new TypeDescriptor(getClass().getField("mapField")).isAssignableTo(new TypeDescriptor(getClass().getField("notGenericMap")))); - assertFalse(new TypeDescriptor(getClass().getField("isAssignableMapKeyValueTypes")).isAssignableTo(new TypeDescriptor(getClass().getField("mapField")))); - assertTrue(TypeDescriptor.valueOf(Map.class).isAssignableTo(new TypeDescriptor(getClass().getField("mapField")))); - } - - public Map notGenericMap; - - public Map<CharSequence, Number> isAssignableMapKeyValueTypes; - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.core.convert; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.Test; + +import org.springframework.core.MethodParameter; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +/** + * @author Keith Donald + * @author Andy Clement + */ +@SuppressWarnings("rawtypes") +public class TypeDescriptorTests { + + public List<String> listOfString; + + public List<List<String>> listOfListOfString = new ArrayList<List<String>>(); + + public List<List> listOfListOfUnknown = new ArrayList<List>(); + + public int[] intArray; + + public List<String>[] arrayOfListOfString; + + public List<Integer> listField = new ArrayList<Integer>(); + + public Map<String, Integer> mapField = new HashMap<String, Integer>(); + + public Map<String, List<Integer>> nestedMapField = new HashMap<String, List<Integer>>(); + + @Test + public void parameterPrimitive() throws Exception { + TypeDescriptor desc = new TypeDescriptor(new MethodParameter(getClass().getMethod("testParameterPrimitive", int.class), 0)); + assertEquals(int.class, desc.getType()); + assertEquals(Integer.class, desc.getObjectType()); + assertEquals("int", desc.getName()); + assertEquals("int", desc.toString()); + assertTrue(desc.isPrimitive()); + assertEquals(0, desc.getAnnotations().length); + assertFalse(desc.isCollection()); + assertFalse(desc.isMap()); + } + + public void testParameterPrimitive(int primitive) { + + } + + @Test + public void parameterScalar() throws Exception { + TypeDescriptor desc = new TypeDescriptor(new MethodParameter(getClass().getMethod("testParameterScalar", String.class), 0)); + assertEquals(String.class, desc.getType()); + assertEquals(String.class, desc.getObjectType()); + assertEquals("java.lang.String", desc.getName()); + assertEquals("java.lang.String", desc.toString()); + assertTrue(!desc.isPrimitive()); + assertEquals(0, desc.getAnnotations().length); + assertFalse(desc.isCollection()); + assertFalse(desc.isArray()); + assertFalse(desc.isMap()); + } + + public void testParameterScalar(String value) { + + } + + @Test + public void parameterList() throws Exception { + MethodParameter methodParameter = new MethodParameter(getClass().getMethod("testParameterList", List.class), 0); + TypeDescriptor desc = new TypeDescriptor(methodParameter); + assertEquals(List.class, desc.getType()); + assertEquals(List.class, desc.getObjectType()); + assertEquals("java.util.List", desc.getName()); + assertEquals("java.util.List<java.util.List<java.util.Map<java.lang.Integer, java.lang.Enum>>>", desc.toString()); + assertTrue(!desc.isPrimitive()); + assertEquals(0, desc.getAnnotations().length); + assertTrue(desc.isCollection()); + assertFalse(desc.isArray()); + assertEquals(List.class, desc.getElementTypeDescriptor().getType()); + assertEquals(TypeDescriptor.nested(methodParameter, 1), desc.getElementTypeDescriptor()); + assertEquals(TypeDescriptor.nested(methodParameter, 2), desc.getElementTypeDescriptor().getElementTypeDescriptor()); + assertEquals(TypeDescriptor.nested(methodParameter, 3), desc.getElementTypeDescriptor().getElementTypeDescriptor().getMapValueTypeDescriptor()); + assertEquals(Integer.class, desc.getElementTypeDescriptor().getElementTypeDescriptor().getMapKeyTypeDescriptor().getType()); + assertEquals(Enum.class, desc.getElementTypeDescriptor().getElementTypeDescriptor().getMapValueTypeDescriptor().getType()); + assertFalse(desc.isMap()); + } + + public void testParameterList(List<List<Map<Integer, Enum<?>>>> list) { + + } + + @Test + public void parameterListNoParamTypes() throws Exception { + MethodParameter methodParameter = new MethodParameter(getClass().getMethod("testParameterListNoParamTypes", List.class), 0); + TypeDescriptor desc = new TypeDescriptor(methodParameter); + assertEquals(List.class, desc.getType()); + assertEquals(List.class, desc.getObjectType()); + assertEquals("java.util.List", desc.getName()); + assertEquals("java.util.List<?>", desc.toString()); + assertTrue(!desc.isPrimitive()); + assertEquals(0, desc.getAnnotations().length); + assertTrue(desc.isCollection()); + assertFalse(desc.isArray()); + assertNull(desc.getElementTypeDescriptor()); + assertFalse(desc.isMap()); + } + + public void testParameterListNoParamTypes(List list) { + + } + + @Test + public void parameterArray() throws Exception { + MethodParameter methodParameter = new MethodParameter(getClass().getMethod("testParameterArray", Integer[].class), 0); + TypeDescriptor desc = new TypeDescriptor(methodParameter); + assertEquals(Integer[].class, desc.getType()); + assertEquals(Integer[].class, desc.getObjectType()); + assertEquals("java.lang.Integer[]", desc.getName()); + assertEquals("java.lang.Integer[]", desc.toString()); + assertTrue(!desc.isPrimitive()); + assertEquals(0, desc.getAnnotations().length); + assertFalse(desc.isCollection()); + assertTrue(desc.isArray()); + assertEquals(Integer.class, desc.getElementTypeDescriptor().getType()); + assertEquals(TypeDescriptor.valueOf(Integer.class), desc.getElementTypeDescriptor()); + assertFalse(desc.isMap()); + } + + public void testParameterArray(Integer[] array) { + + } + + @Test + public void parameterMap() throws Exception { + MethodParameter methodParameter = new MethodParameter(getClass().getMethod("testParameterMap", Map.class), 0); + TypeDescriptor desc = new TypeDescriptor(methodParameter); + assertEquals(Map.class, desc.getType()); + assertEquals(Map.class, desc.getObjectType()); + assertEquals("java.util.Map", desc.getName()); + assertEquals("java.util.Map<java.lang.Integer, java.util.List<java.lang.String>>", desc.toString()); + assertTrue(!desc.isPrimitive()); + assertEquals(0, desc.getAnnotations().length); + assertFalse(desc.isCollection()); + assertFalse(desc.isArray()); + assertTrue(desc.isMap()); + assertEquals(TypeDescriptor.nested(methodParameter, 1), desc.getMapValueTypeDescriptor()); + assertEquals(TypeDescriptor.nested(methodParameter, 2), desc.getMapValueTypeDescriptor().getElementTypeDescriptor()); + assertEquals(Integer.class, desc.getMapKeyTypeDescriptor().getType()); + assertEquals(List.class, desc.getMapValueTypeDescriptor().getType()); + assertEquals(String.class, desc.getMapValueTypeDescriptor().getElementTypeDescriptor().getType()); + } + + public void testParameterMap(Map<Integer, List<String>> map) { + + } + + @Test + public void parameterAnnotated() throws Exception { + TypeDescriptor t1 = new TypeDescriptor(new MethodParameter(getClass().getMethod("testAnnotatedMethod", String.class), 0)); + assertEquals(String.class, t1.getType()); + assertEquals(1, t1.getAnnotations().length); + assertNotNull(t1.getAnnotation(ParameterAnnotation.class)); + } + + @Target({ElementType.PARAMETER}) + @Retention(RetentionPolicy.RUNTIME) + public @interface ParameterAnnotation { + + } + + public void testAnnotatedMethod(@ParameterAnnotation String parameter) { + + } + + @Test + public void propertyComplex() throws Exception { + Property property = new Property(getClass(), getClass().getMethod("getComplexProperty"), getClass().getMethod("setComplexProperty", Map.class)); + TypeDescriptor desc = new TypeDescriptor(property); + assertEquals(String.class, desc.getMapKeyTypeDescriptor().getType()); + assertEquals(Integer.class, desc.getMapValueTypeDescriptor().getElementTypeDescriptor().getElementTypeDescriptor().getType()); + } + + public Map<String, List<List<Integer>>> getComplexProperty() { + return null; + } + + public void setComplexProperty(Map<String, List<List<Integer>>> complexProperty) { + + } + + @Test + public void propertyGenericType() throws Exception { + GenericType<Integer> genericBean = new IntegerType(); + Property property = new Property(getClass(), genericBean.getClass().getMethod("getProperty"), genericBean.getClass().getMethod("setProperty", Integer.class)); + TypeDescriptor desc = new TypeDescriptor(property); + assertEquals(Integer.class, desc.getType()); + } + + @Test + public void propertyTypeCovariance() throws Exception { + GenericType<Number> genericBean = new NumberType(); + Property property = new Property(getClass(), genericBean.getClass().getMethod("getProperty"), genericBean.getClass().getMethod("setProperty", Number.class)); + TypeDescriptor desc = new TypeDescriptor(property); + assertEquals(Integer.class, desc.getType()); + } + + @Test + public void propertyGenericTypeList() throws Exception { + GenericType<Integer> genericBean = new IntegerType(); + Property property = new Property(getClass(), genericBean.getClass().getMethod("getListProperty"), genericBean.getClass().getMethod("setListProperty", List.class)); + TypeDescriptor desc = new TypeDescriptor(property); + assertEquals(List.class, desc.getType()); + assertEquals(Integer.class, desc.getElementTypeDescriptor().getType()); + } + + public interface GenericType<T> { + T getProperty(); + + void setProperty(T t); + + List<T> getListProperty(); + + void setListProperty(List<T> t); + + } + + public class IntegerType implements GenericType<Integer> { + + public Integer getProperty() { + return null; + } + + public void setProperty(Integer t) { + } + + public List<Integer> getListProperty() { + return null; + } + + public void setListProperty(List<Integer> t) { + } + } + + public class NumberType implements GenericType<Number> { + + public Integer getProperty() { + return null; + } + + public void setProperty(Number t) { + } + + public List<Number> getListProperty() { + return null; + } + + public void setListProperty(List<Number> t) { + } + } + + @Test + public void propertyGenericClassList() throws Exception { + IntegerClass genericBean = new IntegerClass(); + Property property = new Property(genericBean.getClass(), genericBean.getClass().getMethod("getListProperty"), genericBean.getClass().getMethod("setListProperty", List.class)); + TypeDescriptor desc = new TypeDescriptor(property); + assertEquals(List.class, desc.getType()); + assertEquals(Integer.class, desc.getElementTypeDescriptor().getType()); + assertNotNull(desc.getAnnotation(MethodAnnotation1.class)); + } + + public static class GenericClass<T> { + + public T getProperty() { + return null; + } + + public void setProperty(T t) { + } + + @MethodAnnotation1 + public List<T> getListProperty() { + return null; + } + + public void setListProperty(List<T> t) { + } + + } + + public static class IntegerClass extends GenericClass<Integer> { + + } + + @Test + public void property() throws Exception { + Property property = new Property(getClass(), getClass().getMethod("getProperty"), getClass().getMethod("setProperty", Map.class)); + TypeDescriptor desc = new TypeDescriptor(property); + assertEquals(Map.class, desc.getType()); + assertEquals(Integer.class, desc.getMapKeyTypeDescriptor().getElementTypeDescriptor().getType()); + assertEquals(Long.class, desc.getMapValueTypeDescriptor().getElementTypeDescriptor().getType()); + assertNotNull(desc.getAnnotation(MethodAnnotation1.class)); + assertNotNull(desc.getAnnotation(MethodAnnotation2.class)); + assertNotNull(desc.getAnnotation(MethodAnnotation3.class)); + } + + @MethodAnnotation1 + public Map<List<Integer>, List<Long>> getProperty() { + return property; + } + + @MethodAnnotation2 + public void setProperty(Map<List<Integer>, List<Long>> property) { + this.property = property; + } + + @MethodAnnotation3 + private Map<List<Integer>, List<Long>> property; + + @Target({ElementType.METHOD}) + @Retention(RetentionPolicy.RUNTIME) + public @interface MethodAnnotation1 { + + } + + @Target({ElementType.METHOD}) + @Retention(RetentionPolicy.RUNTIME) + public @interface MethodAnnotation2 { + + } + + @Target({ElementType.FIELD}) + @Retention(RetentionPolicy.RUNTIME) + public @interface MethodAnnotation3 { + + } + + @Test + public void fieldScalar() throws Exception { + TypeDescriptor typeDescriptor = new TypeDescriptor(getClass().getField("fieldScalar")); + assertFalse(typeDescriptor.isPrimitive()); + assertFalse(typeDescriptor.isArray()); + assertFalse(typeDescriptor.isCollection()); + assertFalse(typeDescriptor.isMap()); + assertEquals(Integer.class, typeDescriptor.getType()); + assertEquals(Integer.class, typeDescriptor.getObjectType()); + } + + public Integer fieldScalar; + + @Test + public void fieldList() throws Exception { + TypeDescriptor typeDescriptor = new TypeDescriptor(TypeDescriptorTests.class.getDeclaredField("listOfString")); + assertFalse(typeDescriptor.isArray()); + assertEquals(List.class, typeDescriptor.getType()); + assertEquals(String.class, typeDescriptor.getElementTypeDescriptor().getType()); + assertEquals("java.util.List<java.lang.String>", typeDescriptor.toString()); + } + + @Test + public void fieldListOfListOfString() throws Exception { + TypeDescriptor typeDescriptor = new TypeDescriptor(TypeDescriptorTests.class.getDeclaredField("listOfListOfString")); + assertFalse(typeDescriptor.isArray()); + assertEquals(List.class, typeDescriptor.getType()); + assertEquals(List.class, typeDescriptor.getElementTypeDescriptor().getType()); + assertEquals(String.class, typeDescriptor.getElementTypeDescriptor().getElementTypeDescriptor().getType()); + assertEquals("java.util.List<java.util.List<java.lang.String>>", typeDescriptor.toString()); + } + + @Test + public void fieldListOfListUnknown() throws Exception { + TypeDescriptor typeDescriptor = new TypeDescriptor(TypeDescriptorTests.class.getDeclaredField("listOfListOfUnknown")); + assertFalse(typeDescriptor.isArray()); + assertEquals(List.class, typeDescriptor.getType()); + assertEquals(List.class, typeDescriptor.getElementTypeDescriptor().getType()); + assertNull(typeDescriptor.getElementTypeDescriptor().getElementTypeDescriptor()); + assertEquals("java.util.List<java.util.List<?>>", typeDescriptor.toString()); + } + + @Test + public void fieldArray() throws Exception { + TypeDescriptor typeDescriptor = new TypeDescriptor(TypeDescriptorTests.class.getDeclaredField("intArray")); + assertTrue(typeDescriptor.isArray()); + assertEquals(Integer.TYPE,typeDescriptor.getElementTypeDescriptor().getType()); + assertEquals("int[]",typeDescriptor.toString()); + } + + @Test + public void fieldComplexTypeDescriptor() throws Exception { + TypeDescriptor typeDescriptor = new TypeDescriptor(TypeDescriptorTests.class.getDeclaredField("arrayOfListOfString")); + assertTrue(typeDescriptor.isArray()); + assertEquals(List.class,typeDescriptor.getElementTypeDescriptor().getType()); + assertEquals(String.class, typeDescriptor.getElementTypeDescriptor().getElementTypeDescriptor().getType()); + assertEquals("java.util.List[]",typeDescriptor.toString()); + } + + @Test + public void fieldComplexTypeDescriptor2() throws Exception { + TypeDescriptor typeDescriptor = new TypeDescriptor(TypeDescriptorTests.class.getDeclaredField("nestedMapField")); + assertTrue(typeDescriptor.isMap()); + assertEquals(String.class,typeDescriptor.getMapKeyTypeDescriptor().getType()); + assertEquals(List.class, typeDescriptor.getMapValueTypeDescriptor().getType()); + assertEquals(Integer.class, typeDescriptor.getMapValueTypeDescriptor().getElementTypeDescriptor().getType()); + assertEquals("java.util.Map<java.lang.String, java.util.List<java.lang.Integer>>", typeDescriptor.toString()); + } + + @Test + public void fieldMap() throws Exception { + TypeDescriptor desc = new TypeDescriptor(TypeDescriptorTests.class.getField("fieldMap")); + assertTrue(desc.isMap()); + assertEquals(Integer.class, desc.getMapKeyTypeDescriptor().getElementTypeDescriptor().getType()); + assertEquals(Long.class, desc.getMapValueTypeDescriptor().getElementTypeDescriptor().getType()); + } + + public Map<List<Integer>, List<Long>> fieldMap; + + @Test + public void fieldAnnotated() throws Exception { + TypeDescriptor typeDescriptor = new TypeDescriptor(getClass().getField("fieldAnnotated")); + assertEquals(1, typeDescriptor.getAnnotations().length); + assertNotNull(typeDescriptor.getAnnotation(FieldAnnotation.class)); + } + + @FieldAnnotation + public List<String> fieldAnnotated; + + @Target({ElementType.FIELD}) + @Retention(RetentionPolicy.RUNTIME) + public @interface FieldAnnotation { + + } + + @Test + public void valueOfScalar() { + TypeDescriptor typeDescriptor = TypeDescriptor.valueOf(Integer.class); + assertFalse(typeDescriptor.isPrimitive()); + assertFalse(typeDescriptor.isArray()); + assertFalse(typeDescriptor.isCollection()); + assertFalse(typeDescriptor.isMap()); + assertEquals(Integer.class, typeDescriptor.getType()); + assertEquals(Integer.class, typeDescriptor.getObjectType()); + } + + @Test + public void valueOfPrimitive() { + TypeDescriptor typeDescriptor = TypeDescriptor.valueOf(int.class); + assertTrue(typeDescriptor.isPrimitive()); + assertFalse(typeDescriptor.isArray()); + assertFalse(typeDescriptor.isCollection()); + assertFalse(typeDescriptor.isMap()); + assertEquals(Integer.TYPE, typeDescriptor.getType()); + assertEquals(Integer.class, typeDescriptor.getObjectType()); + } + + @Test + public void valueOfArray() throws Exception { + TypeDescriptor typeDescriptor = TypeDescriptor.valueOf(int[].class); + assertTrue(typeDescriptor.isArray()); + assertFalse(typeDescriptor.isCollection()); + assertFalse(typeDescriptor.isMap()); + assertEquals(Integer.TYPE, typeDescriptor.getElementTypeDescriptor().getType()); + } + + @Test + public void valueOfCollection() throws Exception { + TypeDescriptor typeDescriptor = TypeDescriptor.valueOf(Collection.class); + assertTrue(typeDescriptor.isCollection()); + assertFalse(typeDescriptor.isArray()); + assertFalse(typeDescriptor.isMap()); + assertNull(typeDescriptor.getElementTypeDescriptor()); + } + + @Test + public void forObject() { + TypeDescriptor desc = TypeDescriptor.forObject("3"); + assertEquals(String.class, desc.getType()); + } + + @Test + public void forObjectNullTypeDescriptor() { + TypeDescriptor desc = TypeDescriptor.forObject(null); + assertNull(desc); + } + + @Test + public void nestedMethodParameterType2Levels() throws Exception { + TypeDescriptor t1 = TypeDescriptor.nested(new MethodParameter(getClass().getMethod("test2", List.class), 0), 2); + assertEquals(String.class, t1.getType()); + } + + @Test + public void nestedMethodParameterTypeMap() throws Exception { + TypeDescriptor t1 = TypeDescriptor.nested(new MethodParameter(getClass().getMethod("test3", Map.class), 0), 1); + assertEquals(String.class, t1.getType()); + } + + @Test + public void nestedMethodParameterTypeMapTwoLevels() throws Exception { + TypeDescriptor t1 = TypeDescriptor.nested(new MethodParameter(getClass().getMethod("test4", List.class), 0), 2); + assertEquals(String.class, t1.getType()); + } + + @Test(expected=IllegalArgumentException.class) + public void nestedMethodParameterNot1NestedLevel() throws Exception { + TypeDescriptor.nested(new MethodParameter(getClass().getMethod("test4", List.class), 0, 2), 2); + } + + @Test(expected=IllegalStateException.class) + public void nestedTooManyLevels() throws Exception { + TypeDescriptor t1 = TypeDescriptor.nested(new MethodParameter(getClass().getMethod("test4", List.class), 0), 3); + assertEquals(String.class, t1.getType()); + } + + @Test(expected=IllegalStateException.class) + public void nestedMethodParameterTypeNotNestable() throws Exception { + TypeDescriptor.nested(new MethodParameter(getClass().getMethod("test5", String.class), 0), 2); + } + + @Test(expected=IllegalArgumentException.class) + public void nestedMethodParameterTypeInvalidNestingLevel() throws Exception { + TypeDescriptor.nested(new MethodParameter(getClass().getMethod("test5", String.class), 0, 2), 2); + } + + public void test1(List<String> param1) { + + } + + public void test2(List<List<String>> param1) { + + } + + public void test3(Map<Integer, String> param1) { + + } + + public void test4(List<Map<Integer, String>> param1) { + + } + + public void test5(String param1) { + + } + + @Test + public void nestedNotParameterized() throws Exception { + TypeDescriptor t1 = TypeDescriptor.nested(new MethodParameter(getClass().getMethod("test6", List.class), 0), 1); + assertEquals(List.class,t1.getType()); + assertEquals("java.util.List<?>", t1.toString()); + TypeDescriptor t2 = TypeDescriptor.nested(new MethodParameter(getClass().getMethod("test6", List.class), 0), 2); + assertNull(t2); + } + + public void test6(List<List> param1) { + + } + + @Test + public void nestedFieldTypeMapTwoLevels() throws Exception { + TypeDescriptor t1 = TypeDescriptor.nested(getClass().getField("test4"), 2); + assertEquals(String.class, t1.getType()); + } + + public List<Map<Integer, String>> test4; + + @Test + public void nestedPropertyTypeMapTwoLevels() throws Exception { + Property property = new Property(getClass(), getClass().getMethod("getTest4"), getClass().getMethod("setTest4", List.class)); + TypeDescriptor t1 = TypeDescriptor.nested(property, 2); + assertEquals(String.class, t1.getType()); + } + + public List<Map<Integer, String>> getTest4() { + return null; + } + + public void setTest4(List<Map<Integer, String>> test4) { + + } + + @Test + public void collection() { + TypeDescriptor desc = TypeDescriptor.collection(List.class, TypeDescriptor.valueOf(Integer.class)); + assertEquals(List.class, desc.getType()); + assertEquals(List.class, desc.getObjectType()); + assertEquals("java.util.List", desc.getName()); + assertEquals("java.util.List<java.lang.Integer>", desc.toString()); + assertTrue(!desc.isPrimitive()); + assertEquals(0, desc.getAnnotations().length); + assertTrue(desc.isCollection()); + assertFalse(desc.isArray()); + assertEquals(Integer.class, desc.getElementTypeDescriptor().getType()); + assertEquals(TypeDescriptor.valueOf(Integer.class), desc.getElementTypeDescriptor()); + assertFalse(desc.isMap()); + } + + @Test + public void collectionNested() { + TypeDescriptor desc = TypeDescriptor.collection(List.class, TypeDescriptor.collection(List.class, TypeDescriptor.valueOf(Integer.class))); + assertEquals(List.class, desc.getType()); + assertEquals(List.class, desc.getObjectType()); + assertEquals("java.util.List", desc.getName()); + assertEquals("java.util.List<java.util.List<java.lang.Integer>>", desc.toString()); + assertTrue(!desc.isPrimitive()); + assertEquals(0, desc.getAnnotations().length); + assertTrue(desc.isCollection()); + assertFalse(desc.isArray()); + assertEquals(List.class, desc.getElementTypeDescriptor().getType()); + assertEquals(TypeDescriptor.valueOf(Integer.class), desc.getElementTypeDescriptor().getElementTypeDescriptor()); + assertFalse(desc.isMap()); + } + + @Test + public void map() { + TypeDescriptor desc = TypeDescriptor.map(Map.class, TypeDescriptor.valueOf(String.class), TypeDescriptor.valueOf(Integer.class)); + assertEquals(Map.class, desc.getType()); + assertEquals(Map.class, desc.getObjectType()); + assertEquals("java.util.Map", desc.getName()); + assertEquals("java.util.Map<java.lang.String, java.lang.Integer>", desc.toString()); + assertTrue(!desc.isPrimitive()); + assertEquals(0, desc.getAnnotations().length); + assertFalse(desc.isCollection()); + assertFalse(desc.isArray()); + assertTrue(desc.isMap()); + assertEquals(String.class, desc.getMapKeyTypeDescriptor().getType()); + assertEquals(Integer.class, desc.getMapValueTypeDescriptor().getType()); + } + + @Test + public void mapNested() { + TypeDescriptor desc = TypeDescriptor.map(Map.class, TypeDescriptor.valueOf(String.class), + TypeDescriptor.map(Map.class, TypeDescriptor.valueOf(String.class), TypeDescriptor.valueOf(Integer.class))); + assertEquals(Map.class, desc.getType()); + assertEquals(Map.class, desc.getObjectType()); + assertEquals("java.util.Map", desc.getName()); + assertEquals("java.util.Map<java.lang.String, java.util.Map<java.lang.String, java.lang.Integer>>", desc.toString()); + assertTrue(!desc.isPrimitive()); + assertEquals(0, desc.getAnnotations().length); + assertFalse(desc.isCollection()); + assertFalse(desc.isArray()); + assertTrue(desc.isMap()); + assertEquals(String.class, desc.getMapKeyTypeDescriptor().getType()); + assertEquals(String.class, desc.getMapValueTypeDescriptor().getMapKeyTypeDescriptor().getType()); + assertEquals(Integer.class, desc.getMapValueTypeDescriptor().getMapValueTypeDescriptor().getType()); + } + + @Test + public void narrow() { + TypeDescriptor desc = TypeDescriptor.valueOf(Number.class); + Integer value = new Integer(3); + desc = desc.narrow(value); + assertEquals(Integer.class, desc.getType()); + } + + @Test + public void elementType() { + TypeDescriptor desc = TypeDescriptor.valueOf(List.class); + Integer value = new Integer(3); + desc = desc.elementTypeDescriptor(value); + assertEquals(Integer.class, desc.getType()); + } + + @Test + public void elementTypePreserveContext() throws Exception { + TypeDescriptor desc = new TypeDescriptor(getClass().getField("listPreserveContext")); + assertEquals(Integer.class, desc.getElementTypeDescriptor().getElementTypeDescriptor().getType()); + List<Integer> value = new ArrayList<Integer>(3); + desc = desc.elementTypeDescriptor(value); + assertEquals(Integer.class, desc.getElementTypeDescriptor().getType()); + assertNotNull(desc.getAnnotation(FieldAnnotation.class)); + } + + @FieldAnnotation + public List<List<Integer>> listPreserveContext; + + @Test + public void mapKeyType() { + TypeDescriptor desc = TypeDescriptor.valueOf(Map.class); + Integer value = new Integer(3); + desc = desc.getMapKeyTypeDescriptor(value); + assertEquals(Integer.class, desc.getType()); + } + + @Test + public void mapKeyTypePreserveContext() throws Exception { + TypeDescriptor desc = new TypeDescriptor(getClass().getField("mapPreserveContext")); + assertEquals(Integer.class, desc.getMapKeyTypeDescriptor().getElementTypeDescriptor().getType()); + List<Integer> value = new ArrayList<Integer>(3); + desc = desc.getMapKeyTypeDescriptor(value); + assertEquals(Integer.class, desc.getElementTypeDescriptor().getType()); + assertNotNull(desc.getAnnotation(FieldAnnotation.class)); + } + + @FieldAnnotation + public Map<List<Integer>, List<Integer>> mapPreserveContext; + + @Test + public void mapValueType() { + TypeDescriptor desc = TypeDescriptor.valueOf(Map.class); + Integer value = new Integer(3); + desc = desc.getMapValueTypeDescriptor(value); + assertEquals(Integer.class, desc.getType()); + } + + @Test + public void mapValueTypePreserveContext() throws Exception { + TypeDescriptor desc = new TypeDescriptor(getClass().getField("mapPreserveContext")); + assertEquals(Integer.class, desc.getMapValueTypeDescriptor().getElementTypeDescriptor().getType()); + List<Integer> value = new ArrayList<Integer>(3); + desc = desc.getMapValueTypeDescriptor(value); + assertEquals(Integer.class, desc.getElementTypeDescriptor().getType()); + assertNotNull(desc.getAnnotation(FieldAnnotation.class)); + } + + @Test + public void equals() throws Exception { + TypeDescriptor t1 = TypeDescriptor.valueOf(String.class); + TypeDescriptor t2 = TypeDescriptor.valueOf(String.class); + TypeDescriptor t3 = TypeDescriptor.valueOf(Date.class); + TypeDescriptor t4 = TypeDescriptor.valueOf(Date.class); + TypeDescriptor t5 = TypeDescriptor.valueOf(List.class); + TypeDescriptor t6 = TypeDescriptor.valueOf(List.class); + TypeDescriptor t7 = TypeDescriptor.valueOf(Map.class); + TypeDescriptor t8 = TypeDescriptor.valueOf(Map.class); + assertEquals(t1, t2); + assertEquals(t3, t4); + assertEquals(t5, t6); + assertEquals(t7, t8); + + TypeDescriptor t9 = new TypeDescriptor(getClass().getField("listField")); + TypeDescriptor t10 = new TypeDescriptor(getClass().getField("listField")); + assertEquals(t9, t10); + + TypeDescriptor t11 = new TypeDescriptor(getClass().getField("mapField")); + TypeDescriptor t12 = new TypeDescriptor(getClass().getField("mapField")); + assertEquals(t11, t12); + } + + @Test + public void isAssignableTypes() { + assertTrue(TypeDescriptor.valueOf(Integer.class).isAssignableTo(TypeDescriptor.valueOf(Number.class))); + assertFalse(TypeDescriptor.valueOf(Number.class).isAssignableTo(TypeDescriptor.valueOf(Integer.class))); + assertFalse(TypeDescriptor.valueOf(String.class).isAssignableTo(TypeDescriptor.valueOf(String[].class))); + } + + @Test + public void isAssignableElementTypes() throws Exception { + assertTrue(new TypeDescriptor(getClass().getField("listField")).isAssignableTo(new TypeDescriptor(getClass().getField("listField")))); + assertTrue(new TypeDescriptor(getClass().getField("notGenericList")).isAssignableTo(new TypeDescriptor(getClass().getField("listField")))); + assertTrue(new TypeDescriptor(getClass().getField("listField")).isAssignableTo(new TypeDescriptor(getClass().getField("notGenericList")))); + assertFalse(new TypeDescriptor(getClass().getField("isAssignableElementTypes")).isAssignableTo(new TypeDescriptor(getClass().getField("listField")))); + assertTrue(TypeDescriptor.valueOf(List.class).isAssignableTo(new TypeDescriptor(getClass().getField("listField")))); + } + + public List notGenericList; + + public List<Number> isAssignableElementTypes; + + @Test + public void isAssignableMapKeyValueTypes() throws Exception { + assertTrue(new TypeDescriptor(getClass().getField("mapField")).isAssignableTo(new TypeDescriptor(getClass().getField("mapField")))); + assertTrue(new TypeDescriptor(getClass().getField("notGenericMap")).isAssignableTo(new TypeDescriptor(getClass().getField("mapField")))); + assertTrue(new TypeDescriptor(getClass().getField("mapField")).isAssignableTo(new TypeDescriptor(getClass().getField("notGenericMap")))); + assertFalse(new TypeDescriptor(getClass().getField("isAssignableMapKeyValueTypes")).isAssignableTo(new TypeDescriptor(getClass().getField("mapField")))); + assertTrue(TypeDescriptor.valueOf(Map.class).isAssignableTo(new TypeDescriptor(getClass().getField("mapField")))); + } + + public Map notGenericMap; + + public Map<CharSequence, Number> isAssignableMapKeyValueTypes; + +} diff --git a/org.springframework.core/src/test/java/org/springframework/core/type/CachingMetadataReaderLeakTest.java b/org.springframework.core/src/test/java/org/springframework/core/type/CachingMetadataReaderLeakTest.java index c01e3df94c5..e6128c35bfb 100644 --- a/org.springframework.core/src/test/java/org/springframework/core/type/CachingMetadataReaderLeakTest.java +++ b/org.springframework.core/src/test/java/org/springframework/core/type/CachingMetadataReaderLeakTest.java @@ -1,79 +1,79 @@ -/* - * Copyright 2006-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.core.type; - -import static org.hamcrest.CoreMatchers.notNullValue; -import static org.junit.Assert.assertThat; - -import java.net.URL; - -import org.junit.Before; -import org.junit.Test; -import org.springframework.core.io.Resource; -import org.springframework.core.io.UrlResource; -import org.springframework.core.type.classreading.CachingMetadataReaderFactory; -import org.springframework.core.type.classreading.MetadataReader; -import org.springframework.core.type.classreading.MetadataReaderFactory; -import org.springframework.core.type.classreading.SimpleMetadataReaderFactory; - -/** - * Unit test checking the behaviour of {@link CachingMetadataReaderFactory under load. - * If the cache is not controller, this test should fail with an out of memory exception around entry - * 5k. - * - * @author Costin Leau - */ -public class CachingMetadataReaderLeakTest { - - private static int ITEMS_LOAD = 9999; - private MetadataReaderFactory mrf; - - @Before - public void before() { - mrf = new CachingMetadataReaderFactory(); - } - - @Test - public void testSignificantLoad() throws Exception { - // the biggest public class in the JDK (>60k) - URL url = getClass().getResource("/java/awt/Component.class"); - assertThat(url, notNullValue()); - - // look at a LOT of items - for (int i = 0; i < ITEMS_LOAD; i++) { - Resource resource = new UrlResource(url) { - private int counter = 0; - - @Override - public boolean equals(Object obj) { - return (obj == this); - - } - - @Override - public int hashCode() { - return System.identityHashCode(this); - } - }; - - MetadataReader reader = mrf.getMetadataReader(resource); - assertThat(reader, notNullValue()); - } - - // useful for profiling to take snapshots - //System.in.read(); - } -} +/* + * Copyright 2006-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.core.type; + +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.junit.Assert.assertThat; + +import java.net.URL; + +import org.junit.Before; +import org.junit.Test; +import org.springframework.core.io.Resource; +import org.springframework.core.io.UrlResource; +import org.springframework.core.type.classreading.CachingMetadataReaderFactory; +import org.springframework.core.type.classreading.MetadataReader; +import org.springframework.core.type.classreading.MetadataReaderFactory; +import org.springframework.core.type.classreading.SimpleMetadataReaderFactory; + +/** + * Unit test checking the behaviour of {@link CachingMetadataReaderFactory under load. + * If the cache is not controller, this test should fail with an out of memory exception around entry + * 5k. + * + * @author Costin Leau + */ +public class CachingMetadataReaderLeakTest { + + private static int ITEMS_LOAD = 9999; + private MetadataReaderFactory mrf; + + @Before + public void before() { + mrf = new CachingMetadataReaderFactory(); + } + + @Test + public void testSignificantLoad() throws Exception { + // the biggest public class in the JDK (>60k) + URL url = getClass().getResource("/java/awt/Component.class"); + assertThat(url, notNullValue()); + + // look at a LOT of items + for (int i = 0; i < ITEMS_LOAD; i++) { + Resource resource = new UrlResource(url) { + private int counter = 0; + + @Override + public boolean equals(Object obj) { + return (obj == this); + + } + + @Override + public int hashCode() { + return System.identityHashCode(this); + } + }; + + MetadataReader reader = mrf.getMetadataReader(resource); + assertThat(reader, notNullValue()); + } + + // useful for profiling to take snapshots + //System.in.read(); + } +} diff --git a/org.springframework.core/src/test/java/org/springframework/util/CompositeIteratorTests.java b/org.springframework.core/src/test/java/org/springframework/util/CompositeIteratorTests.java index a92086e4ea9..451005558e3 100644 --- a/org.springframework.core/src/test/java/org/springframework/util/CompositeIteratorTests.java +++ b/org.springframework.core/src/test/java/org/springframework/util/CompositeIteratorTests.java @@ -1,98 +1,98 @@ -package org.springframework.util; - -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; -import java.util.NoSuchElementException; - -import junit.framework.TestCase; - -/** - * Test case for {@link CompositeIterator}. - * - * @author Erwin Vervaet - */ -public class CompositeIteratorTests extends TestCase { - - public void testNoIterators() { - CompositeIterator it = new CompositeIterator(); - assertFalse(it.hasNext()); - try { - it.next(); - fail(); - } catch (NoSuchElementException e) { - // expected - } - } - - public void testSingleIterator() { - CompositeIterator it = new CompositeIterator(); - it.add(Arrays.asList(new String[] { "0", "1" }).iterator()); - for (int i = 0; i < 2; i++) { - assertTrue(it.hasNext()); - assertEquals(String.valueOf(i), it.next()); - } - assertFalse(it.hasNext()); - try { - it.next(); - fail(); - } catch (NoSuchElementException e) { - // expected - } - } - - public void testMultipleIterators() { - CompositeIterator it = new CompositeIterator(); - it.add(Arrays.asList(new String[] { "0", "1" }).iterator()); - it.add(Arrays.asList(new String[] { "2" }).iterator()); - it.add(Arrays.asList(new String[] { "3", "4" }).iterator()); - for (int i = 0; i < 5; i++) { - assertTrue(it.hasNext()); - assertEquals(String.valueOf(i), it.next()); - } - assertFalse(it.hasNext()); - try { - it.next(); - fail(); - } catch (NoSuchElementException e) { - // expected - } - } - - public void testInUse() { - List list = Arrays.asList(new String[] { "0", "1" }); - CompositeIterator it = new CompositeIterator(); - it.add(list.iterator()); - it.hasNext(); - try { - it.add(list.iterator()); - fail(); - } catch (IllegalStateException e) { - // expected - } - it = new CompositeIterator(); - it.add(list.iterator()); - it.next(); - try { - it.add(list.iterator()); - fail(); - } catch (IllegalStateException e) { - // expected - } - } - - public void testDuplicateIterators() { - List list = Arrays.asList(new String[] { "0", "1" }); - Iterator iterator = list.iterator(); - CompositeIterator it = new CompositeIterator(); - it.add(iterator); - it.add(list.iterator()); - try { - it.add(iterator); - fail(); - } catch (IllegalArgumentException e) { - // expected - } - } - -} +package org.springframework.util; + +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; + +import junit.framework.TestCase; + +/** + * Test case for {@link CompositeIterator}. + * + * @author Erwin Vervaet + */ +public class CompositeIteratorTests extends TestCase { + + public void testNoIterators() { + CompositeIterator it = new CompositeIterator(); + assertFalse(it.hasNext()); + try { + it.next(); + fail(); + } catch (NoSuchElementException e) { + // expected + } + } + + public void testSingleIterator() { + CompositeIterator it = new CompositeIterator(); + it.add(Arrays.asList(new String[] { "0", "1" }).iterator()); + for (int i = 0; i < 2; i++) { + assertTrue(it.hasNext()); + assertEquals(String.valueOf(i), it.next()); + } + assertFalse(it.hasNext()); + try { + it.next(); + fail(); + } catch (NoSuchElementException e) { + // expected + } + } + + public void testMultipleIterators() { + CompositeIterator it = new CompositeIterator(); + it.add(Arrays.asList(new String[] { "0", "1" }).iterator()); + it.add(Arrays.asList(new String[] { "2" }).iterator()); + it.add(Arrays.asList(new String[] { "3", "4" }).iterator()); + for (int i = 0; i < 5; i++) { + assertTrue(it.hasNext()); + assertEquals(String.valueOf(i), it.next()); + } + assertFalse(it.hasNext()); + try { + it.next(); + fail(); + } catch (NoSuchElementException e) { + // expected + } + } + + public void testInUse() { + List list = Arrays.asList(new String[] { "0", "1" }); + CompositeIterator it = new CompositeIterator(); + it.add(list.iterator()); + it.hasNext(); + try { + it.add(list.iterator()); + fail(); + } catch (IllegalStateException e) { + // expected + } + it = new CompositeIterator(); + it.add(list.iterator()); + it.next(); + try { + it.add(list.iterator()); + fail(); + } catch (IllegalStateException e) { + // expected + } + } + + public void testDuplicateIterators() { + List list = Arrays.asList(new String[] { "0", "1" }); + Iterator iterator = list.iterator(); + CompositeIterator it = new CompositeIterator(); + it.add(iterator); + it.add(list.iterator()); + try { + it.add(iterator); + fail(); + } catch (IllegalArgumentException e) { + // expected + } + } + +} diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/AccessException.java b/org.springframework.expression/src/main/java/org/springframework/expression/AccessException.java index 21b4c3bc6c5..d0b41aab6dd 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/AccessException.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/AccessException.java @@ -1,44 +1,44 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.expression; - -/** - * An AccessException is thrown by an accessor if it has an unexpected problem. - * - * @author Andy Clement - * @since 3.0 - */ -public class AccessException extends Exception { - - /** - * Create an AccessException with a specific message and cause. - * @param message the message - * @param cause the cause - */ - public AccessException(String message, Exception cause) { - super(message, cause); - } - - /** - * Create an AccessException with a specific message. - * @param message the message - */ - public AccessException(String message) { - super(message); - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.expression; + +/** + * An AccessException is thrown by an accessor if it has an unexpected problem. + * + * @author Andy Clement + * @since 3.0 + */ +public class AccessException extends Exception { + + /** + * Create an AccessException with a specific message and cause. + * @param message the message + * @param cause the cause + */ + public AccessException(String message, Exception cause) { + super(message, cause); + } + + /** + * Create an AccessException with a specific message. + * @param message the message + */ + public AccessException(String message) { + super(message); + } + +} diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/BeanResolver.java b/org.springframework.expression/src/main/java/org/springframework/expression/BeanResolver.java index 22f164ecb7d..c3857d8e98d 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/BeanResolver.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/BeanResolver.java @@ -1,38 +1,38 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.expression; - -/** - * A bean resolver can be registered with the evaluation context - * and will kick in for <code>@myBeanName</code> still expressions. - * - * @author Andy Clement - * @since 3.0.3 - */ -public interface BeanResolver { - - /** - * Look up the named bean and return it. - * @param context the current evaluation context - * @param beanName the name of the bean to lookup - * @return an object representing the bean - * @throws AccessException if there is an unexpected problem resolving the named bean - */ - Object resolve(EvaluationContext context, String beanName) throws AccessException; - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.expression; + +/** + * A bean resolver can be registered with the evaluation context + * and will kick in for <code>@myBeanName</code> still expressions. + * + * @author Andy Clement + * @since 3.0.3 + */ +public interface BeanResolver { + + /** + * Look up the named bean and return it. + * @param context the current evaluation context + * @param beanName the name of the bean to lookup + * @return an object representing the bean + * @throws AccessException if there is an unexpected problem resolving the named bean + */ + Object resolve(EvaluationContext context, String beanName) throws AccessException; + +} \ No newline at end of file diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/ConstructorExecutor.java b/org.springframework.expression/src/main/java/org/springframework/expression/ConstructorExecutor.java index d0094376eed..34bda66d9e4 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/ConstructorExecutor.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/ConstructorExecutor.java @@ -1,45 +1,45 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.expression; - - -// TODO Is the resolver/executor model too pervasive in this package? -/** - * Executors are built by resolvers and can be cached by the infrastructure to repeat an operation quickly without going - * back to the resolvers. For example, the particular constructor to run on a class may be discovered by the reflection - * constructor resolver - it will then build a ConstructorExecutor that executes that constructor and the - * ConstructorExecutor can be reused without needing to go back to the resolver to discover the constructor again. - * - * They can become stale, and in that case should throw an AccessException - this will cause the infrastructure to go - * back to the resolvers to ask for a new one. - * - * @author Andy Clement - * @since 3.0 - */ -public interface ConstructorExecutor { - - /** - * Execute a constructor in the specified context using the specified arguments. - * @param context the evaluation context in which the command is being executed - * @param arguments the arguments to the constructor call, should match (in terms of number and type) whatever the - * command will need to run - * @return the new object - * @throws AccessException if there is a problem executing the command or the CommandExecutor is no longer valid - */ - TypedValue execute(EvaluationContext context, Object... arguments) throws AccessException; - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.expression; + + +// TODO Is the resolver/executor model too pervasive in this package? +/** + * Executors are built by resolvers and can be cached by the infrastructure to repeat an operation quickly without going + * back to the resolvers. For example, the particular constructor to run on a class may be discovered by the reflection + * constructor resolver - it will then build a ConstructorExecutor that executes that constructor and the + * ConstructorExecutor can be reused without needing to go back to the resolver to discover the constructor again. + * + * They can become stale, and in that case should throw an AccessException - this will cause the infrastructure to go + * back to the resolvers to ask for a new one. + * + * @author Andy Clement + * @since 3.0 + */ +public interface ConstructorExecutor { + + /** + * Execute a constructor in the specified context using the specified arguments. + * @param context the evaluation context in which the command is being executed + * @param arguments the arguments to the constructor call, should match (in terms of number and type) whatever the + * command will need to run + * @return the new object + * @throws AccessException if there is a problem executing the command or the CommandExecutor is no longer valid + */ + TypedValue execute(EvaluationContext context, Object... arguments) throws AccessException; + +} diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/ConstructorResolver.java b/org.springframework.expression/src/main/java/org/springframework/expression/ConstructorResolver.java index 800971791ff..57fb6617119 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/ConstructorResolver.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/ConstructorResolver.java @@ -1,44 +1,44 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.expression; - -import java.util.List; - -import org.springframework.core.convert.TypeDescriptor; - -/** - * A constructor resolver attempts locate a constructor and returns a ConstructorExecutor that can be used to invoke - * that constructor. The ConstructorExecutor will be cached but if it 'goes stale' the resolvers will be called again. - * - * @author Andy Clement - * @since 3.0 - */ -public interface ConstructorResolver { - - /** - * Within the supplied context determine a suitable constructor on the supplied type that can handle the - * specified arguments. Return a ConstructorExecutor that can be used to invoke that constructor - * (or <code>null</code> if no constructor could be found). - * @param context the current evaluation context - * @param typeName the type upon which to look for the constructor - * @param argumentTypes the arguments that the constructor must be able to handle - * @return a ConstructorExecutor that can invoke the constructor, or null if non found - */ - ConstructorExecutor resolve(EvaluationContext context, String typeName, List<TypeDescriptor> argumentTypes) - throws AccessException; - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.expression; + +import java.util.List; + +import org.springframework.core.convert.TypeDescriptor; + +/** + * A constructor resolver attempts locate a constructor and returns a ConstructorExecutor that can be used to invoke + * that constructor. The ConstructorExecutor will be cached but if it 'goes stale' the resolvers will be called again. + * + * @author Andy Clement + * @since 3.0 + */ +public interface ConstructorResolver { + + /** + * Within the supplied context determine a suitable constructor on the supplied type that can handle the + * specified arguments. Return a ConstructorExecutor that can be used to invoke that constructor + * (or <code>null</code> if no constructor could be found). + * @param context the current evaluation context + * @param typeName the type upon which to look for the constructor + * @param argumentTypes the arguments that the constructor must be able to handle + * @return a ConstructorExecutor that can invoke the constructor, or null if non found + */ + ConstructorExecutor resolve(EvaluationContext context, String typeName, List<TypeDescriptor> argumentTypes) + throws AccessException; + +} diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/ExpressionInvocationTargetException.java b/org.springframework.expression/src/main/java/org/springframework/expression/ExpressionInvocationTargetException.java index 4268039b44c..6668fff4150 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/ExpressionInvocationTargetException.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/ExpressionInvocationTargetException.java @@ -1,49 +1,49 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.expression; - -/** - * This exception wraps (as cause) a checked exception thrown by some method that SpEL invokes. - * It differs from a SpelEvaluationException because this indicates the occurrence of a checked exception - * that the invoked method was defined to throw. SpelEvaluationExceptions are for handling (and wrapping) - * unexpected exceptions. - * - * @author Andy Clement - * @since 3.0.3 - */ -public class ExpressionInvocationTargetException extends EvaluationException { - - public ExpressionInvocationTargetException(int position, String message, Throwable cause) { - super(position, message, cause); - } - - public ExpressionInvocationTargetException(int position, String message) { - super(position, message); - } - - public ExpressionInvocationTargetException(String expressionString, String message) { - super(expressionString, message); - } - - public ExpressionInvocationTargetException(String message, Throwable cause) { - super(message, cause); - } - - public ExpressionInvocationTargetException(String message) { - super(message); - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.expression; + +/** + * This exception wraps (as cause) a checked exception thrown by some method that SpEL invokes. + * It differs from a SpelEvaluationException because this indicates the occurrence of a checked exception + * that the invoked method was defined to throw. SpelEvaluationExceptions are for handling (and wrapping) + * unexpected exceptions. + * + * @author Andy Clement + * @since 3.0.3 + */ +public class ExpressionInvocationTargetException extends EvaluationException { + + public ExpressionInvocationTargetException(int position, String message, Throwable cause) { + super(position, message, cause); + } + + public ExpressionInvocationTargetException(int position, String message) { + super(position, message); + } + + public ExpressionInvocationTargetException(String expressionString, String message) { + super(expressionString, message); + } + + public ExpressionInvocationTargetException(String message, Throwable cause) { + super(message, cause); + } + + public ExpressionInvocationTargetException(String message) { + super(message); + } + +} diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/MethodExecutor.java b/org.springframework.expression/src/main/java/org/springframework/expression/MethodExecutor.java index 4093d1c766d..bd4dd74516c 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/MethodExecutor.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/MethodExecutor.java @@ -1,44 +1,44 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.expression; - -/** - * MethodExecutors are built by the resolvers and can be cached by the infrastructure to repeat an operation quickly - * without going back to the resolvers. For example, the particular method to run on an object may be discovered by the - * reflection method resolver - it will then build a MethodExecutor that executes that method and the MethodExecutor can - * be reused without needing to go back to the resolver to discover the method again. - * - * <p>They can become stale, and in that case should throw an AccessException - this will cause the infrastructure to go - * back to the resolvers to ask for a new one. - * - * @author Andy Clement - * @since 3.0 - */ -public interface MethodExecutor { - - /** - * Execute a command using the specified arguments, and using the specified expression state. - * @param context the evaluation context in which the command is being executed - * @param target the target object of the call - null for static methods - * @param arguments the arguments to the executor, should match (in terms of number and type) whatever the - * command will need to run - * @return the value returned from execution - * @throws AccessException if there is a problem executing the command or the MethodExecutor is no longer valid - */ - TypedValue execute(EvaluationContext context, Object target, Object... arguments) throws AccessException; - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.expression; + +/** + * MethodExecutors are built by the resolvers and can be cached by the infrastructure to repeat an operation quickly + * without going back to the resolvers. For example, the particular method to run on an object may be discovered by the + * reflection method resolver - it will then build a MethodExecutor that executes that method and the MethodExecutor can + * be reused without needing to go back to the resolver to discover the method again. + * + * <p>They can become stale, and in that case should throw an AccessException - this will cause the infrastructure to go + * back to the resolvers to ask for a new one. + * + * @author Andy Clement + * @since 3.0 + */ +public interface MethodExecutor { + + /** + * Execute a command using the specified arguments, and using the specified expression state. + * @param context the evaluation context in which the command is being executed + * @param target the target object of the call - null for static methods + * @param arguments the arguments to the executor, should match (in terms of number and type) whatever the + * command will need to run + * @return the value returned from execution + * @throws AccessException if there is a problem executing the command or the MethodExecutor is no longer valid + */ + TypedValue execute(EvaluationContext context, Object target, Object... arguments) throws AccessException; + +} diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/MethodFilter.java b/org.springframework.expression/src/main/java/org/springframework/expression/MethodFilter.java index d81268d226d..b2567425d42 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/MethodFilter.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/MethodFilter.java @@ -1,46 +1,46 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.expression; - -import java.lang.reflect.Method; -import java.util.List; - -/** - * MethodFilter instances allow SpEL users to fine tune the behaviour of the method resolution - * process. Method resolution (which translates from a method name in an expression to a real - * method to invoke) will normally retrieve candidate methods for invocation via a simple call - * to 'Class.getMethods()' and will choose the first one that is suitable for the - * input parameters. By registering a MethodFilter the user can receive a callback - * and change the methods that will be considered suitable. - * - * @author Andy Clement - * @since 3.0.1 - */ -public interface MethodFilter { - - /** - * Called by the method resolver to allow the SpEL user to organize the list of candidate - * methods that may be invoked. The filter can remove methods that should not be - * considered candidates and it may sort the results. The resolver will then search - * through the methods as returned from the filter when looking for a suitable - * candidate to invoke. - * - * @param methods the full list of methods the resolver was going to choose from - * @return a possible subset of input methods that may be sorted by order of relevance - */ - List<Method> filter(List<Method> methods); - +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.expression; + +import java.lang.reflect.Method; +import java.util.List; + +/** + * MethodFilter instances allow SpEL users to fine tune the behaviour of the method resolution + * process. Method resolution (which translates from a method name in an expression to a real + * method to invoke) will normally retrieve candidate methods for invocation via a simple call + * to 'Class.getMethods()' and will choose the first one that is suitable for the + * input parameters. By registering a MethodFilter the user can receive a callback + * and change the methods that will be considered suitable. + * + * @author Andy Clement + * @since 3.0.1 + */ +public interface MethodFilter { + + /** + * Called by the method resolver to allow the SpEL user to organize the list of candidate + * methods that may be invoked. The filter can remove methods that should not be + * considered candidates and it may sort the results. The resolver will then search + * through the methods as returned from the filter when looking for a suitable + * candidate to invoke. + * + * @param methods the full list of methods the resolver was going to choose from + * @return a possible subset of input methods that may be sorted by order of relevance + */ + List<Method> filter(List<Method> methods); + } \ No newline at end of file diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/MethodResolver.java b/org.springframework.expression/src/main/java/org/springframework/expression/MethodResolver.java index fbe3836fc3b..013bedc6a3b 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/MethodResolver.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/MethodResolver.java @@ -1,44 +1,44 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.expression; - -import java.util.List; - -import org.springframework.core.convert.TypeDescriptor; - -/** - * A method resolver attempts locate a method and returns a command executor that can be used to invoke that method. - * The command executor will be cached but if it 'goes stale' the resolvers will be called again. - * - * @author Andy Clement - * @since 3.0 - */ -public interface MethodResolver { - - /** - * Within the supplied context determine a suitable method on the supplied object that can handle the - * specified arguments. Return a MethodExecutor that can be used to invoke that method - * (or <code>null</code> if no method could be found). - * @param context the current evaluation context - * @param targetObject the object upon which the method is being called - * @param argumentTypes the arguments that the constructor must be able to handle - * @return a MethodExecutor that can invoke the method, or null if the method cannot be found - */ - MethodExecutor resolve(EvaluationContext context, Object targetObject, String name, - List<TypeDescriptor> argumentTypes) throws AccessException; - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.expression; + +import java.util.List; + +import org.springframework.core.convert.TypeDescriptor; + +/** + * A method resolver attempts locate a method and returns a command executor that can be used to invoke that method. + * The command executor will be cached but if it 'goes stale' the resolvers will be called again. + * + * @author Andy Clement + * @since 3.0 + */ +public interface MethodResolver { + + /** + * Within the supplied context determine a suitable method on the supplied object that can handle the + * specified arguments. Return a MethodExecutor that can be used to invoke that method + * (or <code>null</code> if no method could be found). + * @param context the current evaluation context + * @param targetObject the object upon which the method is being called + * @param argumentTypes the arguments that the constructor must be able to handle + * @return a MethodExecutor that can invoke the method, or null if the method cannot be found + */ + MethodExecutor resolve(EvaluationContext context, Object targetObject, String name, + List<TypeDescriptor> argumentTypes) throws AccessException; + +} diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/Operation.java b/org.springframework.expression/src/main/java/org/springframework/expression/Operation.java index 38636a2b382..55055a5b4fe 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/Operation.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/Operation.java @@ -1,29 +1,29 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.expression; - -/** - * Supported operations that an {@link OperatorOverloader} can implement for any pair of operands. - * - * @author Andy Clement - * @since 3.0 - */ -public enum Operation { - - ADD, SUBTRACT, DIVIDE, MULTIPLY, MODULUS, POWER - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.expression; + +/** + * Supported operations that an {@link OperatorOverloader} can implement for any pair of operands. + * + * @author Andy Clement + * @since 3.0 + */ +public enum Operation { + + ADD, SUBTRACT, DIVIDE, MULTIPLY, MODULUS, POWER + +} diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/PropertyAccessor.java b/org.springframework.expression/src/main/java/org/springframework/expression/PropertyAccessor.java index 6b080ea3736..c5f474e3cac 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/PropertyAccessor.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/PropertyAccessor.java @@ -1,81 +1,81 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.expression; - - -/** - * A property accessor is able to read (and possibly write) to object properties. The interface places no restrictions - * and so implementors are free to access properties directly as fields or through getters or in any other way they see - * as appropriate. A resolver can optionally specify an array of target classes for which it should be called - but if - * it returns null from getSpecificTargetClasses() then it will be called for all property references and given a chance - * to determine if it can read or write them. Property resolvers are considered to be ordered and each will be called in - * turn. The only rule that affects the call order is that any naming the target class directly in - * getSpecifiedTargetClasses() will be called first, before the general resolvers. - * - * @author Andy Clement - * @since 3.0 - */ -public interface PropertyAccessor { - - /** - * Return an array of classes for which this resolver should be called. Returning null indicates this is a general - * resolver that can be called in an attempt to resolve a property on any type. - * @return an array of classes that this resolver is suitable for (or null if a general resolver) - */ - Class[] getSpecificTargetClasses(); - - /** - * Called to determine if a resolver instance is able to access a specified property on a specified target object. - * @param context the evaluation context in which the access is being attempted - * @param target the target object upon which the property is being accessed - * @param name the name of the property being accessed - * @return true if this resolver is able to read the property - * @throws AccessException if there is any problem determining whether the property can be read - */ - boolean canRead(EvaluationContext context, Object target, String name) throws AccessException; - - /** - * Called to read a property from a specified target object - * @param context the evaluation context in which the access is being attempted - * @param target the target object upon which the property is being accessed - * @param name the name of the property being accessed - * @return a TypedValue object wrapping the property value read and a type descriptor for it - * @throws AccessException if there is any problem accessing the property value - */ - TypedValue read(EvaluationContext context, Object target, String name) throws AccessException; - - /** - * Called to determine if a resolver instance is able to write to a specified property on a specified target object. - * @param context the evaluation context in which the access is being attempted - * @param target the target object upon which the property is being accessed - * @param name the name of the property being accessed - * @return true if this resolver is able to write to the property - * @throws AccessException if there is any problem determining whether the property can be written to - */ - boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException; - - /** - * Called to write to a property on a specified target object. Should only succeed if canWrite() also returns true. - * @param context the evaluation context in which the access is being attempted - * @param target the target object upon which the property is being accessed - * @param name the name of the property being accessed - * @param newValue the new value for the property - * @throws AccessException if there is any problem writing to the property value - */ - void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException; - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.expression; + + +/** + * A property accessor is able to read (and possibly write) to object properties. The interface places no restrictions + * and so implementors are free to access properties directly as fields or through getters or in any other way they see + * as appropriate. A resolver can optionally specify an array of target classes for which it should be called - but if + * it returns null from getSpecificTargetClasses() then it will be called for all property references and given a chance + * to determine if it can read or write them. Property resolvers are considered to be ordered and each will be called in + * turn. The only rule that affects the call order is that any naming the target class directly in + * getSpecifiedTargetClasses() will be called first, before the general resolvers. + * + * @author Andy Clement + * @since 3.0 + */ +public interface PropertyAccessor { + + /** + * Return an array of classes for which this resolver should be called. Returning null indicates this is a general + * resolver that can be called in an attempt to resolve a property on any type. + * @return an array of classes that this resolver is suitable for (or null if a general resolver) + */ + Class[] getSpecificTargetClasses(); + + /** + * Called to determine if a resolver instance is able to access a specified property on a specified target object. + * @param context the evaluation context in which the access is being attempted + * @param target the target object upon which the property is being accessed + * @param name the name of the property being accessed + * @return true if this resolver is able to read the property + * @throws AccessException if there is any problem determining whether the property can be read + */ + boolean canRead(EvaluationContext context, Object target, String name) throws AccessException; + + /** + * Called to read a property from a specified target object + * @param context the evaluation context in which the access is being attempted + * @param target the target object upon which the property is being accessed + * @param name the name of the property being accessed + * @return a TypedValue object wrapping the property value read and a type descriptor for it + * @throws AccessException if there is any problem accessing the property value + */ + TypedValue read(EvaluationContext context, Object target, String name) throws AccessException; + + /** + * Called to determine if a resolver instance is able to write to a specified property on a specified target object. + * @param context the evaluation context in which the access is being attempted + * @param target the target object upon which the property is being accessed + * @param name the name of the property being accessed + * @return true if this resolver is able to write to the property + * @throws AccessException if there is any problem determining whether the property can be written to + */ + boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException; + + /** + * Called to write to a property on a specified target object. Should only succeed if canWrite() also returns true. + * @param context the evaluation context in which the access is being attempted + * @param target the target object upon which the property is being accessed + * @param name the name of the property being accessed + * @param newValue the new value for the property + * @throws AccessException if there is any problem writing to the property value + */ + void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException; + +} diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/TypeConverter.java b/org.springframework.expression/src/main/java/org/springframework/expression/TypeConverter.java index 8ac4ebf9e47..e6145ab20ef 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/TypeConverter.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/TypeConverter.java @@ -1,53 +1,53 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.expression; - -import org.springframework.core.convert.TypeDescriptor; - -/** - * A type converter can convert values between different types encountered - * during expression evaluation. This is an SPI for the expression parser; - * see {@link org.springframework.core.convert.ConversionService} for the - * primary user API to Spring's conversion facilities. - * - * @author Andy Clement - * @author Juergen Hoeller - * @since 3.0 - */ -public interface TypeConverter { - - /** - * Return true if the type converter can convert the specified type to the desired target type. - * @param sourceType a type descriptor that describes the source type - * @param targetType a type descriptor that describes the requested result type - * @return true if that conversion can be performed - */ - boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType); - - /** - * Convert (may coerce) a value from one type to another, for example from a boolean to a string. - * The typeDescriptor parameter enables support for typed collections - if the caller really wishes they - * can have a List<Integer> for example, rather than simply a List. - * @param value the value to be converted - * @param sourceType a type descriptor that supplies extra information about the source object - * @param targetType a type descriptor that supplies extra information about the requested result type - * @return the converted value - * @throws EvaluationException if conversion is not possible - */ - Object convertValue(Object value, TypeDescriptor sourceType, TypeDescriptor targetType); - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.expression; + +import org.springframework.core.convert.TypeDescriptor; + +/** + * A type converter can convert values between different types encountered + * during expression evaluation. This is an SPI for the expression parser; + * see {@link org.springframework.core.convert.ConversionService} for the + * primary user API to Spring's conversion facilities. + * + * @author Andy Clement + * @author Juergen Hoeller + * @since 3.0 + */ +public interface TypeConverter { + + /** + * Return true if the type converter can convert the specified type to the desired target type. + * @param sourceType a type descriptor that describes the source type + * @param targetType a type descriptor that describes the requested result type + * @return true if that conversion can be performed + */ + boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType); + + /** + * Convert (may coerce) a value from one type to another, for example from a boolean to a string. + * The typeDescriptor parameter enables support for typed collections - if the caller really wishes they + * can have a List<Integer> for example, rather than simply a List. + * @param value the value to be converted + * @param sourceType a type descriptor that supplies extra information about the source object + * @param targetType a type descriptor that supplies extra information about the requested result type + * @return the converted value + * @throws EvaluationException if conversion is not possible + */ + Object convertValue(Object value, TypeDescriptor sourceType, TypeDescriptor targetType); + +} diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/TypedValue.java b/org.springframework.expression/src/main/java/org/springframework/expression/TypedValue.java index bf85bd72f3d..ec063ff54c6 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/TypedValue.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/TypedValue.java @@ -1,80 +1,80 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.expression; - -import org.springframework.core.convert.TypeDescriptor; - -/** - * Encapsulates an object and a type descriptor that describes it. - * The type descriptor can hold generic information that would not be - * accessible through a simple <code>getClass()</code> call on the object. - * - * @author Andy Clement - * @author Juergen Hoeller - * @since 3.0 - */ -public class TypedValue { - - public static final TypedValue NULL = new TypedValue(null); - - - private final Object value; - - private TypeDescriptor typeDescriptor; - - - /** - * Create a TypedValue for a simple object. The type descriptor is inferred - * from the object, so no generic information is preserved. - * @param value the object value - */ - public TypedValue(Object value) { - this.value = value; - this.typeDescriptor = null; // initialized when/if requested - } - - /** - * Create a TypedValue for a particular value with a particular type descriptor. - * @param value the object value - * @param typeDescriptor a type descriptor describing the type of the value - */ - public TypedValue(Object value, TypeDescriptor typeDescriptor) { - this.value = value; - this.typeDescriptor = typeDescriptor; - } - - - public Object getValue() { - return this.value; - } - - public TypeDescriptor getTypeDescriptor() { - if (this.typeDescriptor == null) { - this.typeDescriptor = TypeDescriptor.forObject(this.value); - } - return this.typeDescriptor; - } - - - @Override - public String toString() { - StringBuilder str = new StringBuilder(); - str.append("TypedValue: '").append(this.value).append("' of [").append(getTypeDescriptor() + "]"); - return str.toString(); - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.expression; + +import org.springframework.core.convert.TypeDescriptor; + +/** + * Encapsulates an object and a type descriptor that describes it. + * The type descriptor can hold generic information that would not be + * accessible through a simple <code>getClass()</code> call on the object. + * + * @author Andy Clement + * @author Juergen Hoeller + * @since 3.0 + */ +public class TypedValue { + + public static final TypedValue NULL = new TypedValue(null); + + + private final Object value; + + private TypeDescriptor typeDescriptor; + + + /** + * Create a TypedValue for a simple object. The type descriptor is inferred + * from the object, so no generic information is preserved. + * @param value the object value + */ + public TypedValue(Object value) { + this.value = value; + this.typeDescriptor = null; // initialized when/if requested + } + + /** + * Create a TypedValue for a particular value with a particular type descriptor. + * @param value the object value + * @param typeDescriptor a type descriptor describing the type of the value + */ + public TypedValue(Object value, TypeDescriptor typeDescriptor) { + this.value = value; + this.typeDescriptor = typeDescriptor; + } + + + public Object getValue() { + return this.value; + } + + public TypeDescriptor getTypeDescriptor() { + if (this.typeDescriptor == null) { + this.typeDescriptor = TypeDescriptor.forObject(this.value); + } + return this.typeDescriptor; + } + + + @Override + public String toString() { + StringBuilder str = new StringBuilder(); + str.append("TypedValue: '").append(this.value).append("' of [").append(getTypeDescriptor() + "]"); + return str.toString(); + } + +} diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/common/TemplateParserContext.java b/org.springframework.expression/src/main/java/org/springframework/expression/common/TemplateParserContext.java index fb6251038b1..c1ed129dec3 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/common/TemplateParserContext.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/common/TemplateParserContext.java @@ -1,65 +1,65 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.expression.common; - -import org.springframework.expression.ParserContext; - -/** - * Configurable {@link ParserContext} implementation for template parsing. - * Expects the expression prefix and suffix as constructor arguments. - * - * @author Juergen Hoeller - * @since 3.0 - */ -public class TemplateParserContext implements ParserContext { - - private final String expressionPrefix; - - private final String expressionSuffix; - - - /** - * Create a new TemplateParserContext with the default "#{" prefix and "}" suffix. - */ - public TemplateParserContext() { - this("#{", "}"); - } - - /** - * Create a new TemplateParserContext for the given prefix and suffix. - * @param expressionPrefix the expression prefix to use - * @param expressionSuffix the expression suffix to use - */ - public TemplateParserContext(String expressionPrefix, String expressionSuffix) { - this.expressionPrefix = expressionPrefix; - this.expressionSuffix = expressionSuffix; - } - - - public final boolean isTemplate() { - return true; - } - - public final String getExpressionPrefix() { - return this.expressionPrefix; - } - - public final String getExpressionSuffix() { - return this.expressionSuffix; - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.expression.common; + +import org.springframework.expression.ParserContext; + +/** + * Configurable {@link ParserContext} implementation for template parsing. + * Expects the expression prefix and suffix as constructor arguments. + * + * @author Juergen Hoeller + * @since 3.0 + */ +public class TemplateParserContext implements ParserContext { + + private final String expressionPrefix; + + private final String expressionSuffix; + + + /** + * Create a new TemplateParserContext with the default "#{" prefix and "}" suffix. + */ + public TemplateParserContext() { + this("#{", "}"); + } + + /** + * Create a new TemplateParserContext for the given prefix and suffix. + * @param expressionPrefix the expression prefix to use + * @param expressionSuffix the expression suffix to use + */ + public TemplateParserContext(String expressionPrefix, String expressionSuffix) { + this.expressionPrefix = expressionPrefix; + this.expressionSuffix = expressionSuffix; + } + + + public final boolean isTemplate() { + return true; + } + + public final String getExpressionPrefix() { + return this.expressionPrefix; + } + + public final String getExpressionSuffix() { + return this.expressionSuffix; + } + +} diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/spel/ExpressionState.java b/org.springframework.expression/src/main/java/org/springframework/expression/spel/ExpressionState.java index 5eb3ce8a882..09f51cfe813 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/spel/ExpressionState.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/spel/ExpressionState.java @@ -1,242 +1,242 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.expression.spel; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Stack; - -import org.springframework.core.convert.TypeDescriptor; -import org.springframework.expression.EvaluationContext; -import org.springframework.expression.EvaluationException; -import org.springframework.expression.Operation; -import org.springframework.expression.OperatorOverloader; -import org.springframework.expression.PropertyAccessor; -import org.springframework.expression.TypeComparator; -import org.springframework.expression.TypedValue; - -/** - * An ExpressionState is for maintaining per-expression-evaluation state, any changes to it are not seen by other - * expressions but it gives a place to hold local variables and for component expressions in a compound expression to - * communicate state. This is in contrast to the EvaluationContext, which is shared amongst expression evaluations, and - * any changes to it will be seen by other expressions or any code that chooses to ask questions of the context. - * - * <p>It also acts as a place for to define common utility routines that the various Ast nodes might need. - * - * @author Andy Clement - * @since 3.0 - */ -public class ExpressionState { - - private final EvaluationContext relatedContext; - - private Stack<VariableScope> variableScopes; - - private Stack<TypedValue> contextObjects; - - private final TypedValue rootObject; - - private SpelParserConfiguration configuration; - - - public ExpressionState(EvaluationContext context) { - this.relatedContext = context; - this.rootObject = context.getRootObject(); - } - - public ExpressionState(EvaluationContext context, SpelParserConfiguration configuration) { - this.relatedContext = context; - this.configuration = configuration; - this.rootObject = context.getRootObject(); - } - - public ExpressionState(EvaluationContext context, TypedValue rootObject) { - this.relatedContext = context; - this.rootObject = rootObject; - } - - public ExpressionState(EvaluationContext context, TypedValue rootObject, SpelParserConfiguration configuration) { - this.relatedContext = context; - this.configuration = configuration; - this.rootObject = rootObject; - } - - - private void ensureVariableScopesInitialized() { - if (this.variableScopes == null) { - this.variableScopes = new Stack<VariableScope>(); - // top level empty variable scope - this.variableScopes.add(new VariableScope()); - } - } - - /** - * The active context object is what unqualified references to properties/etc are resolved against. - */ - public TypedValue getActiveContextObject() { - if (this.contextObjects==null || this.contextObjects.isEmpty()) { - return this.rootObject; - } - - return this.contextObjects.peek(); - } - - public void pushActiveContextObject(TypedValue obj) { - if (this.contextObjects==null) { - this.contextObjects = new Stack<TypedValue>(); - } - this.contextObjects.push(obj); - } - - public void popActiveContextObject() { - if (this.contextObjects==null) { - this.contextObjects = new Stack<TypedValue>(); - } - this.contextObjects.pop(); - } - - public TypedValue getRootContextObject() { - return this.rootObject; - } - - public void setVariable(String name, Object value) { - this.relatedContext.setVariable(name, value); - } - - public TypedValue lookupVariable(String name) { - Object value = this.relatedContext.lookupVariable(name); - if (value == null) { - return TypedValue.NULL; - } - else { - return new TypedValue(value); - } - } - - public TypeComparator getTypeComparator() { - return this.relatedContext.getTypeComparator(); - } - - public Class<?> findType(String type) throws EvaluationException { - return this.relatedContext.getTypeLocator().findType(type); - } - - public Object convertValue(Object value, TypeDescriptor targetTypeDescriptor) throws EvaluationException { - return this.relatedContext.getTypeConverter().convertValue(value, TypeDescriptor.forObject(value), targetTypeDescriptor); - } - - public Object convertValue(TypedValue value, TypeDescriptor targetTypeDescriptor) throws EvaluationException { - Object val = value.getValue(); - return this.relatedContext.getTypeConverter().convertValue(val, TypeDescriptor.forObject(val), targetTypeDescriptor); - } - - /* - * A new scope is entered when a function is invoked - */ - - public void enterScope(Map<String, Object> argMap) { - ensureVariableScopesInitialized(); - this.variableScopes.push(new VariableScope(argMap)); - } - - public void enterScope(String name, Object value) { - ensureVariableScopesInitialized(); - this.variableScopes.push(new VariableScope(name, value)); - } - - public void exitScope() { - ensureVariableScopesInitialized(); - this.variableScopes.pop(); - } - - public void setLocalVariable(String name, Object value) { - ensureVariableScopesInitialized(); - this.variableScopes.peek().setVariable(name, value); - } - - public Object lookupLocalVariable(String name) { - ensureVariableScopesInitialized(); - int scopeNumber = this.variableScopes.size() - 1; - for (int i = scopeNumber; i >= 0; i--) { - if (this.variableScopes.get(i).definesVariable(name)) { - return this.variableScopes.get(i).lookupVariable(name); - } - } - return null; - } - - public TypedValue operate(Operation op, Object left, Object right) throws EvaluationException { - OperatorOverloader overloader = this.relatedContext.getOperatorOverloader(); - if (overloader.overridesOperation(op, left, right)) { - Object returnValue = overloader.operate(op, left, right); - return new TypedValue(returnValue); - } - else { - String leftType = (left==null?"null":left.getClass().getName()); - String rightType = (right==null?"null":right.getClass().getName()); - throw new SpelEvaluationException(SpelMessage.OPERATOR_NOT_SUPPORTED_BETWEEN_TYPES, op, leftType, rightType); - } - } - - public List<PropertyAccessor> getPropertyAccessors() { - return this.relatedContext.getPropertyAccessors(); - } - - public EvaluationContext getEvaluationContext() { - return this.relatedContext; - } - - public SpelParserConfiguration getConfiguration() { - return this.configuration; - } - - /** - * A new scope is entered when a function is called and it is used to hold the parameters to the function call. If the names - * of the parameters clash with those in a higher level scope, those in the higher level scope will not be accessible whilst - * the function is executing. When the function returns the scope is exited. - */ - private static class VariableScope { - - private final Map<String, Object> vars = new HashMap<String, Object>(); - - public VariableScope() { } - - public VariableScope(Map<String, Object> arguments) { - if (arguments != null) { - this.vars.putAll(arguments); - } - } - - public VariableScope(String name, Object value) { - this.vars.put(name,value); - } - - public Object lookupVariable(String name) { - return this.vars.get(name); - } - - public void setVariable(String name, Object value) { - this.vars.put(name,value); - } - - public boolean definesVariable(String name) { - return this.vars.containsKey(name); - } - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.expression.spel; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Stack; + +import org.springframework.core.convert.TypeDescriptor; +import org.springframework.expression.EvaluationContext; +import org.springframework.expression.EvaluationException; +import org.springframework.expression.Operation; +import org.springframework.expression.OperatorOverloader; +import org.springframework.expression.PropertyAccessor; +import org.springframework.expression.TypeComparator; +import org.springframework.expression.TypedValue; + +/** + * An ExpressionState is for maintaining per-expression-evaluation state, any changes to it are not seen by other + * expressions but it gives a place to hold local variables and for component expressions in a compound expression to + * communicate state. This is in contrast to the EvaluationContext, which is shared amongst expression evaluations, and + * any changes to it will be seen by other expressions or any code that chooses to ask questions of the context. + * + * <p>It also acts as a place for to define common utility routines that the various Ast nodes might need. + * + * @author Andy Clement + * @since 3.0 + */ +public class ExpressionState { + + private final EvaluationContext relatedContext; + + private Stack<VariableScope> variableScopes; + + private Stack<TypedValue> contextObjects; + + private final TypedValue rootObject; + + private SpelParserConfiguration configuration; + + + public ExpressionState(EvaluationContext context) { + this.relatedContext = context; + this.rootObject = context.getRootObject(); + } + + public ExpressionState(EvaluationContext context, SpelParserConfiguration configuration) { + this.relatedContext = context; + this.configuration = configuration; + this.rootObject = context.getRootObject(); + } + + public ExpressionState(EvaluationContext context, TypedValue rootObject) { + this.relatedContext = context; + this.rootObject = rootObject; + } + + public ExpressionState(EvaluationContext context, TypedValue rootObject, SpelParserConfiguration configuration) { + this.relatedContext = context; + this.configuration = configuration; + this.rootObject = rootObject; + } + + + private void ensureVariableScopesInitialized() { + if (this.variableScopes == null) { + this.variableScopes = new Stack<VariableScope>(); + // top level empty variable scope + this.variableScopes.add(new VariableScope()); + } + } + + /** + * The active context object is what unqualified references to properties/etc are resolved against. + */ + public TypedValue getActiveContextObject() { + if (this.contextObjects==null || this.contextObjects.isEmpty()) { + return this.rootObject; + } + + return this.contextObjects.peek(); + } + + public void pushActiveContextObject(TypedValue obj) { + if (this.contextObjects==null) { + this.contextObjects = new Stack<TypedValue>(); + } + this.contextObjects.push(obj); + } + + public void popActiveContextObject() { + if (this.contextObjects==null) { + this.contextObjects = new Stack<TypedValue>(); + } + this.contextObjects.pop(); + } + + public TypedValue getRootContextObject() { + return this.rootObject; + } + + public void setVariable(String name, Object value) { + this.relatedContext.setVariable(name, value); + } + + public TypedValue lookupVariable(String name) { + Object value = this.relatedContext.lookupVariable(name); + if (value == null) { + return TypedValue.NULL; + } + else { + return new TypedValue(value); + } + } + + public TypeComparator getTypeComparator() { + return this.relatedContext.getTypeComparator(); + } + + public Class<?> findType(String type) throws EvaluationException { + return this.relatedContext.getTypeLocator().findType(type); + } + + public Object convertValue(Object value, TypeDescriptor targetTypeDescriptor) throws EvaluationException { + return this.relatedContext.getTypeConverter().convertValue(value, TypeDescriptor.forObject(value), targetTypeDescriptor); + } + + public Object convertValue(TypedValue value, TypeDescriptor targetTypeDescriptor) throws EvaluationException { + Object val = value.getValue(); + return this.relatedContext.getTypeConverter().convertValue(val, TypeDescriptor.forObject(val), targetTypeDescriptor); + } + + /* + * A new scope is entered when a function is invoked + */ + + public void enterScope(Map<String, Object> argMap) { + ensureVariableScopesInitialized(); + this.variableScopes.push(new VariableScope(argMap)); + } + + public void enterScope(String name, Object value) { + ensureVariableScopesInitialized(); + this.variableScopes.push(new VariableScope(name, value)); + } + + public void exitScope() { + ensureVariableScopesInitialized(); + this.variableScopes.pop(); + } + + public void setLocalVariable(String name, Object value) { + ensureVariableScopesInitialized(); + this.variableScopes.peek().setVariable(name, value); + } + + public Object lookupLocalVariable(String name) { + ensureVariableScopesInitialized(); + int scopeNumber = this.variableScopes.size() - 1; + for (int i = scopeNumber; i >= 0; i--) { + if (this.variableScopes.get(i).definesVariable(name)) { + return this.variableScopes.get(i).lookupVariable(name); + } + } + return null; + } + + public TypedValue operate(Operation op, Object left, Object right) throws EvaluationException { + OperatorOverloader overloader = this.relatedContext.getOperatorOverloader(); + if (overloader.overridesOperation(op, left, right)) { + Object returnValue = overloader.operate(op, left, right); + return new TypedValue(returnValue); + } + else { + String leftType = (left==null?"null":left.getClass().getName()); + String rightType = (right==null?"null":right.getClass().getName()); + throw new SpelEvaluationException(SpelMessage.OPERATOR_NOT_SUPPORTED_BETWEEN_TYPES, op, leftType, rightType); + } + } + + public List<PropertyAccessor> getPropertyAccessors() { + return this.relatedContext.getPropertyAccessors(); + } + + public EvaluationContext getEvaluationContext() { + return this.relatedContext; + } + + public SpelParserConfiguration getConfiguration() { + return this.configuration; + } + + /** + * A new scope is entered when a function is called and it is used to hold the parameters to the function call. If the names + * of the parameters clash with those in a higher level scope, those in the higher level scope will not be accessible whilst + * the function is executing. When the function returns the scope is exited. + */ + private static class VariableScope { + + private final Map<String, Object> vars = new HashMap<String, Object>(); + + public VariableScope() { } + + public VariableScope(Map<String, Object> arguments) { + if (arguments != null) { + this.vars.putAll(arguments); + } + } + + public VariableScope(String name, Object value) { + this.vars.put(name,value); + } + + public Object lookupVariable(String name) { + return this.vars.get(name); + } + + public void setVariable(String name, Object value) { + this.vars.put(name,value); + } + + public boolean definesVariable(String name) { + return this.vars.containsKey(name); + } + } + +} diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/spel/InternalParseException.java b/org.springframework.expression/src/main/java/org/springframework/expression/spel/InternalParseException.java index ac76105e287..fd3dcb5549c 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/spel/InternalParseException.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/spel/InternalParseException.java @@ -1,38 +1,38 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.expression.spel; - -import org.springframework.expression.spel.SpelParseException; - -/** - * Wraps a real parse exception. This exception flows to the top parse method and then - * the wrapped exception is thrown as the real problem. - * - * @author Andy Clement - * @since 3.0 - */ -public class InternalParseException extends RuntimeException { - - public InternalParseException(SpelParseException cause) { - super(cause); - } - - public SpelParseException getCause() { - return (SpelParseException) super.getCause(); - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.expression.spel; + +import org.springframework.expression.spel.SpelParseException; + +/** + * Wraps a real parse exception. This exception flows to the top parse method and then + * the wrapped exception is thrown as the real problem. + * + * @author Andy Clement + * @since 3.0 + */ +public class InternalParseException extends RuntimeException { + + public InternalParseException(SpelParseException cause) { + super(cause); + } + + public SpelParseException getCause() { + return (SpelParseException) super.getCause(); + } + +} diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/spel/SpelEvaluationException.java b/org.springframework.expression/src/main/java/org/springframework/expression/spel/SpelEvaluationException.java index c7c3161781d..e736d3bf740 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/spel/SpelEvaluationException.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/spel/SpelEvaluationException.java @@ -1,92 +1,92 @@ -/* - * Copyright 2004-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.expression.spel; - -import org.springframework.expression.EvaluationException; - -/** - * Root exception for Spring EL related exceptions. Rather than holding a hard coded string indicating the problem, it - * records a message key and the inserts for the message. See {@link SpelMessage} for the list of all possible messages - * that can occur. - * - * @author Andy Clement - * @since 3.0 - */ -public class SpelEvaluationException extends EvaluationException { - - private SpelMessage message; - private Object[] inserts; - - public SpelEvaluationException(SpelMessage message, Object... inserts) { - super(message.formatMessage(0, inserts)); // TODO poor position information, can the callers not really supply something? - this.message = message; - this.inserts = inserts; - } - - public SpelEvaluationException(int position, SpelMessage message, Object... inserts) { - super(position, message.formatMessage(position, inserts)); - this.message = message; - this.inserts = inserts; - } - - public SpelEvaluationException(int position, Throwable cause, - SpelMessage message, Object... inserts) { - super(position,message.formatMessage(position,inserts),cause); - this.message = message; - this.inserts = inserts; - } - - public SpelEvaluationException(Throwable cause, SpelMessage message, Object... inserts) { - super(message.formatMessage(0,inserts),cause); - this.message = message; - this.inserts = inserts; - } - - /** - * @return a formatted message with inserts applied - */ - @Override - public String getMessage() { - if (message != null) - return message.formatMessage(position, inserts); - else - return super.getMessage(); - } - - /** - * @return the message code - */ - public SpelMessage getMessageCode() { - return this.message; - } - - /** - * Set the position in the related expression which gave rise to this exception. - * - * @param position the position in the expression that gave rise to the exception - */ - public void setPosition(int position) { - this.position = position; - } - - /** - * @return the message inserts - */ - public Object[] getInserts() { - return inserts; - } - -} +/* + * Copyright 2004-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.expression.spel; + +import org.springframework.expression.EvaluationException; + +/** + * Root exception for Spring EL related exceptions. Rather than holding a hard coded string indicating the problem, it + * records a message key and the inserts for the message. See {@link SpelMessage} for the list of all possible messages + * that can occur. + * + * @author Andy Clement + * @since 3.0 + */ +public class SpelEvaluationException extends EvaluationException { + + private SpelMessage message; + private Object[] inserts; + + public SpelEvaluationException(SpelMessage message, Object... inserts) { + super(message.formatMessage(0, inserts)); // TODO poor position information, can the callers not really supply something? + this.message = message; + this.inserts = inserts; + } + + public SpelEvaluationException(int position, SpelMessage message, Object... inserts) { + super(position, message.formatMessage(position, inserts)); + this.message = message; + this.inserts = inserts; + } + + public SpelEvaluationException(int position, Throwable cause, + SpelMessage message, Object... inserts) { + super(position,message.formatMessage(position,inserts),cause); + this.message = message; + this.inserts = inserts; + } + + public SpelEvaluationException(Throwable cause, SpelMessage message, Object... inserts) { + super(message.formatMessage(0,inserts),cause); + this.message = message; + this.inserts = inserts; + } + + /** + * @return a formatted message with inserts applied + */ + @Override + public String getMessage() { + if (message != null) + return message.formatMessage(position, inserts); + else + return super.getMessage(); + } + + /** + * @return the message code + */ + public SpelMessage getMessageCode() { + return this.message; + } + + /** + * Set the position in the related expression which gave rise to this exception. + * + * @param position the position in the expression that gave rise to the exception + */ + public void setPosition(int position) { + this.position = position; + } + + /** + * @return the message inserts + */ + public Object[] getInserts() { + return inserts; + } + +} diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/spel/SpelMessage.java b/org.springframework.expression/src/main/java/org/springframework/expression/spel/SpelMessage.java index 459bed1ea4c..14f0bfb9b93 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/spel/SpelMessage.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/spel/SpelMessage.java @@ -1,156 +1,156 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.expression.spel; - -import java.text.MessageFormat; - -/** - * Contains all the messages that can be produced by the Spring Expression Language. Each message has a kind (info, - * warn, error) and a code number. Tests can be written to expect particular code numbers rather than particular text, - * enabling the message text to more easily be modified and the tests to run successfully in different locales. - * <p> - * When a message is formatted, it will have this kind of form - * - * <pre> - * EL1004E: (pos 34): Type cannot be found 'String' - * </pre> - * - * </code> The prefix captures the code and the error kind, whilst the position is included if it is known. - * - * @author Andy Clement - * @since 3.0 - */ -public enum SpelMessage { - - TYPE_CONVERSION_ERROR(Kind.ERROR, 1001, "Type conversion problem, cannot convert from {0} to {1}"), // - CONSTRUCTOR_NOT_FOUND(Kind.ERROR, 1002, "Constructor call: No suitable constructor found on type {0} for arguments {1}"), // - CONSTRUCTOR_INVOCATION_PROBLEM(Kind.ERROR, 1003, "A problem occurred whilst attempting to construct an object of type ''{0}'' using arguments ''{1}''"), // - METHOD_NOT_FOUND(Kind.ERROR, 1004, "Method call: Method {0} cannot be found on {1} type"), // - TYPE_NOT_FOUND(Kind.ERROR, 1005, "Type cannot be found ''{0}''"), // - FUNCTION_NOT_DEFINED(Kind.ERROR, 1006, "The function ''{0}'' could not be found"), // - PROPERTY_OR_FIELD_NOT_READABLE_ON_NULL(Kind.ERROR, 1007, "Field or property ''{0}'' cannot be found on null"), // - PROPERTY_OR_FIELD_NOT_READABLE(Kind.ERROR, 1008, "Field or property ''{0}'' cannot be found on object of type ''{1}''"), // - PROPERTY_OR_FIELD_NOT_WRITABLE_ON_NULL(Kind.ERROR, 1009, "Field or property ''{0}'' cannot be set on null"), // - PROPERTY_OR_FIELD_NOT_WRITABLE(Kind.ERROR, 1010, "Field or property ''{0}'' cannot be set on object of type ''{1}''"), // - METHOD_CALL_ON_NULL_OBJECT_NOT_ALLOWED(Kind.ERROR, 1011, "Method call: Attempted to call method {0} on null context object"), // - CANNOT_INDEX_INTO_NULL_VALUE(Kind.ERROR, 1012, "Cannot index into a null value"), - NOT_COMPARABLE(Kind.ERROR, 1013, "Cannot compare instances of {0} and {1}"), // - INCORRECT_NUMBER_OF_ARGUMENTS_TO_FUNCTION(Kind.ERROR, 1014, "Incorrect number of arguments for function, {0} supplied but function takes {1}"), // - INVALID_TYPE_FOR_SELECTION(Kind.ERROR, 1015, "Cannot perform selection on input data of type ''{0}''"), // - RESULT_OF_SELECTION_CRITERIA_IS_NOT_BOOLEAN(Kind.ERROR, 1016, "Result of selection criteria is not boolean"), // - BETWEEN_RIGHT_OPERAND_MUST_BE_TWO_ELEMENT_LIST(Kind.ERROR, 1017, "Right operand for the 'between' operator has to be a two-element list"), // - INVALID_PATTERN(Kind.ERROR, 1018, "Pattern is not valid ''{0}''"), // - PROJECTION_NOT_SUPPORTED_ON_TYPE(Kind.ERROR, 1019, "Projection is not supported on the type ''{0}''"), // - ARGLIST_SHOULD_NOT_BE_EVALUATED(Kind.ERROR, 1020, "The argument list of a lambda expression should never have getValue() called upon it"), // - EXCEPTION_DURING_PROPERTY_READ(Kind.ERROR, 1021, "A problem occurred whilst attempting to access the property ''{0}'': ''{1}''"), // - FUNCTION_REFERENCE_CANNOT_BE_INVOKED(Kind.ERROR, 1022, "The function ''{0}'' mapped to an object of type ''{1}'' which cannot be invoked"), // - EXCEPTION_DURING_FUNCTION_CALL(Kind.ERROR, 1023, "A problem occurred whilst attempting to invoke the function ''{0}'': ''{1}''"), // - ARRAY_INDEX_OUT_OF_BOUNDS(Kind.ERROR, 1024, "The array has ''{0}'' elements, index ''{1}'' is invalid"), // - COLLECTION_INDEX_OUT_OF_BOUNDS(Kind.ERROR, 1025, "The collection has ''{0}'' elements, index ''{1}'' is invalid"), // - STRING_INDEX_OUT_OF_BOUNDS(Kind.ERROR, 1026, "The string has ''{0}'' characters, index ''{1}'' is invalid"), // - INDEXING_NOT_SUPPORTED_FOR_TYPE(Kind.ERROR, 1027, "Indexing into type ''{0}'' is not supported"), // - INSTANCEOF_OPERATOR_NEEDS_CLASS_OPERAND(Kind.ERROR, 1028, "The operator 'instanceof' needs the right operand to be a class, not a ''{0}''"), // - EXCEPTION_DURING_METHOD_INVOCATION(Kind.ERROR, 1029, "A problem occurred when trying to execute method ''{0}'' on object of type ''{1}'': ''{2}''"), // - OPERATOR_NOT_SUPPORTED_BETWEEN_TYPES(Kind.ERROR, 1030, "The operator ''{0}'' is not supported between objects of type ''{1}'' and ''{2}''"), // - PROBLEM_LOCATING_METHOD(Kind.ERROR, 1031, "Problem locating method {0} cannot on type {1}"), - SETVALUE_NOT_SUPPORTED( Kind.ERROR, 1032, "setValue(ExpressionState, Object) not supported for ''{0}''"), // - MULTIPLE_POSSIBLE_METHODS(Kind.ERROR, 1033, "Method call of ''{0}'' is ambiguous, supported type conversions allow multiple variants to match"), // - EXCEPTION_DURING_PROPERTY_WRITE(Kind.ERROR, 1034, "A problem occurred whilst attempting to set the property ''{0}'': {1}"), // - NOT_AN_INTEGER(Kind.ERROR, 1035, "The value ''{0}'' cannot be parsed as an int"), // - NOT_A_LONG(Kind.ERROR, 1036, "The value ''{0}'' cannot be parsed as a long"), // - INVALID_FIRST_OPERAND_FOR_MATCHES_OPERATOR(Kind.ERROR, 1037, "First operand to matches operator must be a string. ''{0}'' is not"), // - INVALID_SECOND_OPERAND_FOR_MATCHES_OPERATOR(Kind.ERROR, 1038, "Second operand to matches operator must be a string. ''{0}'' is not"), // - FUNCTION_MUST_BE_STATIC(Kind.ERROR, 1039, "Only static methods can be called via function references. The method ''{0}'' referred to by name ''{1}'' is not static."),// - NOT_A_REAL(Kind.ERROR, 1040, "The value ''{0}'' cannot be parsed as a double"), // - MORE_INPUT(Kind.ERROR,1041, "After parsing a valid expression, there is still more data in the expression: ''{0}''"), - RIGHT_OPERAND_PROBLEM(Kind.ERROR,1042, "Problem parsing right operand"), - NOT_EXPECTED_TOKEN(Kind.ERROR,1043,"Unexpected token. Expected ''{0}'' but was ''{1}''"), - OOD(Kind.ERROR,1044,"Unexpectedly ran out of input"), // - NON_TERMINATING_DOUBLE_QUOTED_STRING(Kind.ERROR,1045,"Cannot find terminating \" for string"),// - NON_TERMINATING_QUOTED_STRING(Kind.ERROR,1046,"Cannot find terminating ' for string"), // - MISSING_LEADING_ZERO_FOR_NUMBER(Kind.ERROR,1047,"A real number must be prefixed by zero, it cannot start with just ''.''"), // - REAL_CANNOT_BE_LONG(Kind.ERROR,1048,"Real number cannot be suffixed with a long (L or l) suffix"),// - UNEXPECTED_DATA_AFTER_DOT(Kind.ERROR,1049,"Unexpected data after ''.'': ''{0}''"),// - MISSING_CONSTRUCTOR_ARGS(Kind.ERROR,1050,"The arguments '(...)' for the constructor call are missing"),// - RUN_OUT_OF_ARGUMENTS(Kind.ERROR,1051,"Unexpected ran out of arguments"),// - UNABLE_TO_GROW_COLLECTION(Kind.ERROR,1052,"Unable to grow collection"),// - UNABLE_TO_GROW_COLLECTION_UNKNOWN_ELEMENT_TYPE(Kind.ERROR,1053,"Unable to grow collection: unable to determine list element type"),// - UNABLE_TO_CREATE_LIST_FOR_INDEXING(Kind.ERROR,1054,"Unable to dynamically create a List to replace a null value"),// - UNABLE_TO_CREATE_MAP_FOR_INDEXING(Kind.ERROR,1055,"Unable to dynamically create a Map to replace a null value"),// - UNABLE_TO_DYNAMICALLY_CREATE_OBJECT(Kind.ERROR,1056,"Unable to dynamically create instance of ''{0}'' to replace a null value"),// - NO_BEAN_RESOLVER_REGISTERED(Kind.ERROR,1057,"No bean resolver registered in the context to resolve access to bean ''{0}''"),// - EXCEPTION_DURING_BEAN_RESOLUTION(Kind.ERROR, 1058, "A problem occurred when trying to resolve bean ''{0}'':''{1}''"), // - INVALID_BEAN_REFERENCE(Kind.ERROR,1059,"@ can only be followed by an identifier or a quoted name"),// - TYPE_NAME_EXPECTED_FOR_ARRAY_CONSTRUCTION(Kind.ERROR, 1060, - "Expected the type of the new array to be specified as a String but found ''{0}''"), // - INCORRECT_ELEMENT_TYPE_FOR_ARRAY(Kind.ERROR, 1061, - "The array of type ''{0}'' cannot have an element of type ''{1}'' inserted"), // - MULTIDIM_ARRAY_INITIALIZER_NOT_SUPPORTED(Kind.ERROR, 1062, - "Using an initializer to build a multi-dimensional array is not currently supported"), // - MISSING_ARRAY_DIMENSION(Kind.ERROR, 1063, "A required array dimension has not been specified"), // - INITIALIZER_LENGTH_INCORRECT( - Kind.ERROR, 1064, "array initializer size does not match array dimensions"), // - ; - - private Kind kind; - private int code; - private String message; - - - private SpelMessage(Kind kind, int code, String message) { - this.kind = kind; - this.code = code; - this.message = message; - } - - - /** - * Produce a complete message including the prefix, the position (if known) and with the inserts applied to the - * message. - * - * @param pos the position, if less than zero it is ignored and not included in the message - * @param inserts the inserts to put into the formatted message - * @return a formatted message - */ - public String formatMessage(int pos, Object... inserts) { - StringBuilder formattedMessage = new StringBuilder(); - formattedMessage.append("EL").append(code); - switch (kind) { -// case WARNING: -// formattedMessage.append("W"); -// break; -// case INFO: -// formattedMessage.append("I"); -// break; - case ERROR: - formattedMessage.append("E"); - break; - } - formattedMessage.append(":"); - if (pos != -1) { - formattedMessage.append("(pos ").append(pos).append("): "); - } - formattedMessage.append(MessageFormat.format(message, inserts)); - return formattedMessage.toString(); - } - - - public static enum Kind { - INFO, WARNING, ERROR - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.expression.spel; + +import java.text.MessageFormat; + +/** + * Contains all the messages that can be produced by the Spring Expression Language. Each message has a kind (info, + * warn, error) and a code number. Tests can be written to expect particular code numbers rather than particular text, + * enabling the message text to more easily be modified and the tests to run successfully in different locales. + * <p> + * When a message is formatted, it will have this kind of form + * + * <pre> + * EL1004E: (pos 34): Type cannot be found 'String' + * </pre> + * + * </code> The prefix captures the code and the error kind, whilst the position is included if it is known. + * + * @author Andy Clement + * @since 3.0 + */ +public enum SpelMessage { + + TYPE_CONVERSION_ERROR(Kind.ERROR, 1001, "Type conversion problem, cannot convert from {0} to {1}"), // + CONSTRUCTOR_NOT_FOUND(Kind.ERROR, 1002, "Constructor call: No suitable constructor found on type {0} for arguments {1}"), // + CONSTRUCTOR_INVOCATION_PROBLEM(Kind.ERROR, 1003, "A problem occurred whilst attempting to construct an object of type ''{0}'' using arguments ''{1}''"), // + METHOD_NOT_FOUND(Kind.ERROR, 1004, "Method call: Method {0} cannot be found on {1} type"), // + TYPE_NOT_FOUND(Kind.ERROR, 1005, "Type cannot be found ''{0}''"), // + FUNCTION_NOT_DEFINED(Kind.ERROR, 1006, "The function ''{0}'' could not be found"), // + PROPERTY_OR_FIELD_NOT_READABLE_ON_NULL(Kind.ERROR, 1007, "Field or property ''{0}'' cannot be found on null"), // + PROPERTY_OR_FIELD_NOT_READABLE(Kind.ERROR, 1008, "Field or property ''{0}'' cannot be found on object of type ''{1}''"), // + PROPERTY_OR_FIELD_NOT_WRITABLE_ON_NULL(Kind.ERROR, 1009, "Field or property ''{0}'' cannot be set on null"), // + PROPERTY_OR_FIELD_NOT_WRITABLE(Kind.ERROR, 1010, "Field or property ''{0}'' cannot be set on object of type ''{1}''"), // + METHOD_CALL_ON_NULL_OBJECT_NOT_ALLOWED(Kind.ERROR, 1011, "Method call: Attempted to call method {0} on null context object"), // + CANNOT_INDEX_INTO_NULL_VALUE(Kind.ERROR, 1012, "Cannot index into a null value"), + NOT_COMPARABLE(Kind.ERROR, 1013, "Cannot compare instances of {0} and {1}"), // + INCORRECT_NUMBER_OF_ARGUMENTS_TO_FUNCTION(Kind.ERROR, 1014, "Incorrect number of arguments for function, {0} supplied but function takes {1}"), // + INVALID_TYPE_FOR_SELECTION(Kind.ERROR, 1015, "Cannot perform selection on input data of type ''{0}''"), // + RESULT_OF_SELECTION_CRITERIA_IS_NOT_BOOLEAN(Kind.ERROR, 1016, "Result of selection criteria is not boolean"), // + BETWEEN_RIGHT_OPERAND_MUST_BE_TWO_ELEMENT_LIST(Kind.ERROR, 1017, "Right operand for the 'between' operator has to be a two-element list"), // + INVALID_PATTERN(Kind.ERROR, 1018, "Pattern is not valid ''{0}''"), // + PROJECTION_NOT_SUPPORTED_ON_TYPE(Kind.ERROR, 1019, "Projection is not supported on the type ''{0}''"), // + ARGLIST_SHOULD_NOT_BE_EVALUATED(Kind.ERROR, 1020, "The argument list of a lambda expression should never have getValue() called upon it"), // + EXCEPTION_DURING_PROPERTY_READ(Kind.ERROR, 1021, "A problem occurred whilst attempting to access the property ''{0}'': ''{1}''"), // + FUNCTION_REFERENCE_CANNOT_BE_INVOKED(Kind.ERROR, 1022, "The function ''{0}'' mapped to an object of type ''{1}'' which cannot be invoked"), // + EXCEPTION_DURING_FUNCTION_CALL(Kind.ERROR, 1023, "A problem occurred whilst attempting to invoke the function ''{0}'': ''{1}''"), // + ARRAY_INDEX_OUT_OF_BOUNDS(Kind.ERROR, 1024, "The array has ''{0}'' elements, index ''{1}'' is invalid"), // + COLLECTION_INDEX_OUT_OF_BOUNDS(Kind.ERROR, 1025, "The collection has ''{0}'' elements, index ''{1}'' is invalid"), // + STRING_INDEX_OUT_OF_BOUNDS(Kind.ERROR, 1026, "The string has ''{0}'' characters, index ''{1}'' is invalid"), // + INDEXING_NOT_SUPPORTED_FOR_TYPE(Kind.ERROR, 1027, "Indexing into type ''{0}'' is not supported"), // + INSTANCEOF_OPERATOR_NEEDS_CLASS_OPERAND(Kind.ERROR, 1028, "The operator 'instanceof' needs the right operand to be a class, not a ''{0}''"), // + EXCEPTION_DURING_METHOD_INVOCATION(Kind.ERROR, 1029, "A problem occurred when trying to execute method ''{0}'' on object of type ''{1}'': ''{2}''"), // + OPERATOR_NOT_SUPPORTED_BETWEEN_TYPES(Kind.ERROR, 1030, "The operator ''{0}'' is not supported between objects of type ''{1}'' and ''{2}''"), // + PROBLEM_LOCATING_METHOD(Kind.ERROR, 1031, "Problem locating method {0} cannot on type {1}"), + SETVALUE_NOT_SUPPORTED( Kind.ERROR, 1032, "setValue(ExpressionState, Object) not supported for ''{0}''"), // + MULTIPLE_POSSIBLE_METHODS(Kind.ERROR, 1033, "Method call of ''{0}'' is ambiguous, supported type conversions allow multiple variants to match"), // + EXCEPTION_DURING_PROPERTY_WRITE(Kind.ERROR, 1034, "A problem occurred whilst attempting to set the property ''{0}'': {1}"), // + NOT_AN_INTEGER(Kind.ERROR, 1035, "The value ''{0}'' cannot be parsed as an int"), // + NOT_A_LONG(Kind.ERROR, 1036, "The value ''{0}'' cannot be parsed as a long"), // + INVALID_FIRST_OPERAND_FOR_MATCHES_OPERATOR(Kind.ERROR, 1037, "First operand to matches operator must be a string. ''{0}'' is not"), // + INVALID_SECOND_OPERAND_FOR_MATCHES_OPERATOR(Kind.ERROR, 1038, "Second operand to matches operator must be a string. ''{0}'' is not"), // + FUNCTION_MUST_BE_STATIC(Kind.ERROR, 1039, "Only static methods can be called via function references. The method ''{0}'' referred to by name ''{1}'' is not static."),// + NOT_A_REAL(Kind.ERROR, 1040, "The value ''{0}'' cannot be parsed as a double"), // + MORE_INPUT(Kind.ERROR,1041, "After parsing a valid expression, there is still more data in the expression: ''{0}''"), + RIGHT_OPERAND_PROBLEM(Kind.ERROR,1042, "Problem parsing right operand"), + NOT_EXPECTED_TOKEN(Kind.ERROR,1043,"Unexpected token. Expected ''{0}'' but was ''{1}''"), + OOD(Kind.ERROR,1044,"Unexpectedly ran out of input"), // + NON_TERMINATING_DOUBLE_QUOTED_STRING(Kind.ERROR,1045,"Cannot find terminating \" for string"),// + NON_TERMINATING_QUOTED_STRING(Kind.ERROR,1046,"Cannot find terminating ' for string"), // + MISSING_LEADING_ZERO_FOR_NUMBER(Kind.ERROR,1047,"A real number must be prefixed by zero, it cannot start with just ''.''"), // + REAL_CANNOT_BE_LONG(Kind.ERROR,1048,"Real number cannot be suffixed with a long (L or l) suffix"),// + UNEXPECTED_DATA_AFTER_DOT(Kind.ERROR,1049,"Unexpected data after ''.'': ''{0}''"),// + MISSING_CONSTRUCTOR_ARGS(Kind.ERROR,1050,"The arguments '(...)' for the constructor call are missing"),// + RUN_OUT_OF_ARGUMENTS(Kind.ERROR,1051,"Unexpected ran out of arguments"),// + UNABLE_TO_GROW_COLLECTION(Kind.ERROR,1052,"Unable to grow collection"),// + UNABLE_TO_GROW_COLLECTION_UNKNOWN_ELEMENT_TYPE(Kind.ERROR,1053,"Unable to grow collection: unable to determine list element type"),// + UNABLE_TO_CREATE_LIST_FOR_INDEXING(Kind.ERROR,1054,"Unable to dynamically create a List to replace a null value"),// + UNABLE_TO_CREATE_MAP_FOR_INDEXING(Kind.ERROR,1055,"Unable to dynamically create a Map to replace a null value"),// + UNABLE_TO_DYNAMICALLY_CREATE_OBJECT(Kind.ERROR,1056,"Unable to dynamically create instance of ''{0}'' to replace a null value"),// + NO_BEAN_RESOLVER_REGISTERED(Kind.ERROR,1057,"No bean resolver registered in the context to resolve access to bean ''{0}''"),// + EXCEPTION_DURING_BEAN_RESOLUTION(Kind.ERROR, 1058, "A problem occurred when trying to resolve bean ''{0}'':''{1}''"), // + INVALID_BEAN_REFERENCE(Kind.ERROR,1059,"@ can only be followed by an identifier or a quoted name"),// + TYPE_NAME_EXPECTED_FOR_ARRAY_CONSTRUCTION(Kind.ERROR, 1060, + "Expected the type of the new array to be specified as a String but found ''{0}''"), // + INCORRECT_ELEMENT_TYPE_FOR_ARRAY(Kind.ERROR, 1061, + "The array of type ''{0}'' cannot have an element of type ''{1}'' inserted"), // + MULTIDIM_ARRAY_INITIALIZER_NOT_SUPPORTED(Kind.ERROR, 1062, + "Using an initializer to build a multi-dimensional array is not currently supported"), // + MISSING_ARRAY_DIMENSION(Kind.ERROR, 1063, "A required array dimension has not been specified"), // + INITIALIZER_LENGTH_INCORRECT( + Kind.ERROR, 1064, "array initializer size does not match array dimensions"), // + ; + + private Kind kind; + private int code; + private String message; + + + private SpelMessage(Kind kind, int code, String message) { + this.kind = kind; + this.code = code; + this.message = message; + } + + + /** + * Produce a complete message including the prefix, the position (if known) and with the inserts applied to the + * message. + * + * @param pos the position, if less than zero it is ignored and not included in the message + * @param inserts the inserts to put into the formatted message + * @return a formatted message + */ + public String formatMessage(int pos, Object... inserts) { + StringBuilder formattedMessage = new StringBuilder(); + formattedMessage.append("EL").append(code); + switch (kind) { +// case WARNING: +// formattedMessage.append("W"); +// break; +// case INFO: +// formattedMessage.append("I"); +// break; + case ERROR: + formattedMessage.append("E"); + break; + } + formattedMessage.append(":"); + if (pos != -1) { + formattedMessage.append("(pos ").append(pos).append("): "); + } + formattedMessage.append(MessageFormat.format(message, inserts)); + return formattedMessage.toString(); + } + + + public static enum Kind { + INFO, WARNING, ERROR + } + +} diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/spel/SpelNode.java b/org.springframework.expression/src/main/java/org/springframework/expression/spel/SpelNode.java index d0decbac718..392807ae16e 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/spel/SpelNode.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/spel/SpelNode.java @@ -1,95 +1,95 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.expression.spel; - -import org.springframework.expression.EvaluationException; -import org.springframework.expression.TypedValue; - -/** - * Represents a node in the Ast for a parsed expression. - * - * @author Andy Clement - * @since 3.0 - */ -public interface SpelNode { - - /** - * Evaluate the expression node in the context of the supplied expression state and return the value. - * @param expressionState the current expression state (includes the context) - * @return the value of this node evaluated against the specified state - */ - Object getValue(ExpressionState expressionState) throws EvaluationException; - - /** - * Evaluate the expression node in the context of the supplied expression state and return the typed value. - * @param expressionState the current expression state (includes the context) - * @return the type value of this node evaluated against the specified state - */ - TypedValue getTypedValue(ExpressionState expressionState) throws EvaluationException; - - /** - * Determine if this expression node will support a setValue() call. - * - * @param expressionState the current expression state (includes the context) - * @return true if the expression node will allow setValue() - * @throws EvaluationException if something went wrong trying to determine if the node supports writing - */ - boolean isWritable(ExpressionState expressionState) throws EvaluationException; - - /** - * Evaluate the expression to a node and then set the new value on that node. For example, if the expression - * evaluates to a property reference then the property will be set to the new value. - * @param expressionState the current expression state (includes the context) - * @param newValue the new value - * @throws EvaluationException if any problem occurs evaluating the expression or setting the new value - */ - void setValue(ExpressionState expressionState, Object newValue) throws EvaluationException; - - /** - * @return the string form of this AST node - */ - String toStringAST(); - - /** - * @return the number of children under this node - */ - int getChildCount(); - - /** - * Helper method that returns a SpelNode rather than an Antlr Tree node. - * @return the child node cast to a SpelNode - */ - SpelNode getChild(int index); - - /** - * Determine the class of the object passed in, unless it is already a class object. - * @param o the object that the caller wants the class of - * @return the class of the object if it is not already a class object, or null if the object is null - */ - Class<?> getObjectClass(Object obj); - - /** - * @return the start position of this Ast node in the expression string - */ - int getStartPosition(); - - /** - * @return the end position of this Ast node in the expression string - */ - int getEndPosition(); - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.expression.spel; + +import org.springframework.expression.EvaluationException; +import org.springframework.expression.TypedValue; + +/** + * Represents a node in the Ast for a parsed expression. + * + * @author Andy Clement + * @since 3.0 + */ +public interface SpelNode { + + /** + * Evaluate the expression node in the context of the supplied expression state and return the value. + * @param expressionState the current expression state (includes the context) + * @return the value of this node evaluated against the specified state + */ + Object getValue(ExpressionState expressionState) throws EvaluationException; + + /** + * Evaluate the expression node in the context of the supplied expression state and return the typed value. + * @param expressionState the current expression state (includes the context) + * @return the type value of this node evaluated against the specified state + */ + TypedValue getTypedValue(ExpressionState expressionState) throws EvaluationException; + + /** + * Determine if this expression node will support a setValue() call. + * + * @param expressionState the current expression state (includes the context) + * @return true if the expression node will allow setValue() + * @throws EvaluationException if something went wrong trying to determine if the node supports writing + */ + boolean isWritable(ExpressionState expressionState) throws EvaluationException; + + /** + * Evaluate the expression to a node and then set the new value on that node. For example, if the expression + * evaluates to a property reference then the property will be set to the new value. + * @param expressionState the current expression state (includes the context) + * @param newValue the new value + * @throws EvaluationException if any problem occurs evaluating the expression or setting the new value + */ + void setValue(ExpressionState expressionState, Object newValue) throws EvaluationException; + + /** + * @return the string form of this AST node + */ + String toStringAST(); + + /** + * @return the number of children under this node + */ + int getChildCount(); + + /** + * Helper method that returns a SpelNode rather than an Antlr Tree node. + * @return the child node cast to a SpelNode + */ + SpelNode getChild(int index); + + /** + * Determine the class of the object passed in, unless it is already a class object. + * @param o the object that the caller wants the class of + * @return the class of the object if it is not already a class object, or null if the object is null + */ + Class<?> getObjectClass(Object obj); + + /** + * @return the start position of this Ast node in the expression string + */ + int getStartPosition(); + + /** + * @return the end position of this Ast node in the expression string + */ + int getEndPosition(); + +} diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/spel/SpelParseException.java b/org.springframework.expression/src/main/java/org/springframework/expression/spel/SpelParseException.java index 03672eb7f4f..3b8c14ff130 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/spel/SpelParseException.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/spel/SpelParseException.java @@ -1,107 +1,107 @@ -/* - * Copyright 2004-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.expression.spel; - -import org.springframework.expression.ParseException; - - -/** - * Root exception for Spring EL related exceptions. Rather than holding a hard coded string indicating the problem, it - * records a message key and the inserts for the message. See {@link SpelMessage} for the list of all possible messages - * that can occur. - * - * @author Andy Clement - * @since 3.0 - */ -public class SpelParseException extends ParseException { - - private SpelMessage message; - private Object[] inserts; - -// public SpelParseException(String expressionString, int position, Throwable cause, SpelMessages message, Object... inserts) { -// super(expressionString, position, message.formatMessage(position,inserts), cause); -// this.message = message; -// this.inserts = inserts; -// } - - public SpelParseException(String expressionString, int position, SpelMessage message, Object... inserts) { - super(expressionString, position, message.formatMessage(position,inserts)); - this.position = position; - this.message = message; - this.inserts = inserts; - } - - public SpelParseException(int position, SpelMessage message, Object... inserts) { - super(position, message.formatMessage(position,inserts)); - this.position = position; - this.message = message; - this.inserts = inserts; - } - - public SpelParseException(int position, Throwable cause, SpelMessage message, Object... inserts) { - super(position, message.formatMessage(position,inserts), cause); - this.position = position; - this.message = message; - this.inserts = inserts; - } - -// -// public SpelException(Throwable cause, SpelMessages message, Object... inserts) { -// super(cause); -// this.message = message; -// this.inserts = inserts; -// } -// -// public SpelException(int position, SpelMessages message, Object... inserts) { -// super((Throwable)null); -// this.position = position; -// this.message = message; -// this.inserts = inserts; -// } -// -// public SpelException(SpelMessages message, Object... inserts) { -// super((Throwable)null); -// this.message = message; -// this.inserts = inserts; -// } - - - /** - * @return a formatted message with inserts applied - */ - @Override - public String getMessage() { - if (message != null) - return message.formatMessage(position, inserts); - else - return super.getMessage(); - } - - /** - * @return the message code - */ - public SpelMessage getMessageCode() { - return this.message; - } - - /** - * @return the message inserts - */ - public Object[] getInserts() { - return inserts; - } - -} +/* + * Copyright 2004-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.expression.spel; + +import org.springframework.expression.ParseException; + + +/** + * Root exception for Spring EL related exceptions. Rather than holding a hard coded string indicating the problem, it + * records a message key and the inserts for the message. See {@link SpelMessage} for the list of all possible messages + * that can occur. + * + * @author Andy Clement + * @since 3.0 + */ +public class SpelParseException extends ParseException { + + private SpelMessage message; + private Object[] inserts; + +// public SpelParseException(String expressionString, int position, Throwable cause, SpelMessages message, Object... inserts) { +// super(expressionString, position, message.formatMessage(position,inserts), cause); +// this.message = message; +// this.inserts = inserts; +// } + + public SpelParseException(String expressionString, int position, SpelMessage message, Object... inserts) { + super(expressionString, position, message.formatMessage(position,inserts)); + this.position = position; + this.message = message; + this.inserts = inserts; + } + + public SpelParseException(int position, SpelMessage message, Object... inserts) { + super(position, message.formatMessage(position,inserts)); + this.position = position; + this.message = message; + this.inserts = inserts; + } + + public SpelParseException(int position, Throwable cause, SpelMessage message, Object... inserts) { + super(position, message.formatMessage(position,inserts), cause); + this.position = position; + this.message = message; + this.inserts = inserts; + } + +// +// public SpelException(Throwable cause, SpelMessages message, Object... inserts) { +// super(cause); +// this.message = message; +// this.inserts = inserts; +// } +// +// public SpelException(int position, SpelMessages message, Object... inserts) { +// super((Throwable)null); +// this.position = position; +// this.message = message; +// this.inserts = inserts; +// } +// +// public SpelException(SpelMessages message, Object... inserts) { +// super((Throwable)null); +// this.message = message; +// this.inserts = inserts; +// } + + + /** + * @return a formatted message with inserts applied + */ + @Override + public String getMessage() { + if (message != null) + return message.formatMessage(position, inserts); + else + return super.getMessage(); + } + + /** + * @return the message code + */ + public SpelMessage getMessageCode() { + return this.message; + } + + /** + * @return the message inserts + */ + public Object[] getInserts() { + return inserts; + } + +} diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/spel/SpelParserConfiguration.java b/org.springframework.expression/src/main/java/org/springframework/expression/spel/SpelParserConfiguration.java index 5787b7e549a..c9e7bad2f1e 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/spel/SpelParserConfiguration.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/spel/SpelParserConfiguration.java @@ -1,47 +1,47 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.expression.spel; - -/** - * Configuration object for the SpEL expression parser. - * - * @author Juergen Hoeller - * @since 3.0 - * @see org.springframework.expression.spel.standard.SpelExpressionParser#SpelExpressionParser(SpelParserConfiguration) - */ -public class SpelParserConfiguration { - - private final boolean autoGrowNullReferences; - - private final boolean autoGrowCollections; - - - public SpelParserConfiguration(boolean autoGrowNullReferences, boolean autoGrowCollections) { - this.autoGrowNullReferences = autoGrowNullReferences; - this.autoGrowCollections = autoGrowCollections; - } - - - public boolean isAutoGrowNullReferences() { - return this.autoGrowNullReferences; - } - - public boolean isAutoGrowCollections() { - return this.autoGrowCollections; - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.expression.spel; + +/** + * Configuration object for the SpEL expression parser. + * + * @author Juergen Hoeller + * @since 3.0 + * @see org.springframework.expression.spel.standard.SpelExpressionParser#SpelExpressionParser(SpelParserConfiguration) + */ +public class SpelParserConfiguration { + + private final boolean autoGrowNullReferences; + + private final boolean autoGrowCollections; + + + public SpelParserConfiguration(boolean autoGrowNullReferences, boolean autoGrowCollections) { + this.autoGrowNullReferences = autoGrowNullReferences; + this.autoGrowCollections = autoGrowCollections; + } + + + public boolean isAutoGrowNullReferences() { + return this.autoGrowNullReferences; + } + + public boolean isAutoGrowCollections() { + return this.autoGrowCollections; + } + +} diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/AstUtils.java b/org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/AstUtils.java index ff998fef137..2d0aa726113 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/AstUtils.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/AstUtils.java @@ -1,72 +1,72 @@ -/* - * Copyright 2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.expression.spel.ast; - -import java.util.ArrayList; -import java.util.List; - -import org.springframework.expression.PropertyAccessor; -import org.springframework.expression.spel.ExpressionState; - -/** - * Utilities methods for use in the Ast classes. - * - * @author Andy Clement - * @since 3.0.2 - */ -public class AstUtils { - - /** - * Determines the set of property resolvers that should be used to try and access a property on the specified target - * type. The resolvers are considered to be in an ordered list, however in the returned list any that are exact - * matches for the input target type (as opposed to 'general' resolvers that could work for any type) are placed at - * the start of the list. In addition, there are specific resolvers that exactly name the class in question and - * resolvers that name a specific class but it is a supertype of the class we have. These are put at the end of the - * specific resolvers set and will be tried after exactly matching accessors but before generic accessors. - * - * @param targetType the type upon which property access is being attempted - * @return a list of resolvers that should be tried in order to access the property - */ - public static List<PropertyAccessor> getPropertyAccessorsToTry(Class<?> targetType, ExpressionState state) { - List<PropertyAccessor> specificAccessors = new ArrayList<PropertyAccessor>(); - List<PropertyAccessor> generalAccessors = new ArrayList<PropertyAccessor>(); - for (PropertyAccessor resolver : state.getPropertyAccessors()) { - Class<?>[] targets = resolver.getSpecificTargetClasses(); - if (targets == null) { // generic resolver that says it can be used for any type - generalAccessors.add(resolver); - } - else { - if (targetType != null) { - int pos = 0; - for (Class<?> clazz : targets) { - if (clazz == targetType) { // put exact matches on the front to be tried first? - specificAccessors.add(pos++, resolver); - } - else if (clazz.isAssignableFrom(targetType)) { // put supertype matches at the end of the - // specificAccessor list - generalAccessors.add(resolver); - } - } - } - } - } - List<PropertyAccessor> resolvers = new ArrayList<PropertyAccessor>(); - resolvers.addAll(specificAccessors); - resolvers.addAll(generalAccessors); - return resolvers; - } -} +/* + * Copyright 2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.expression.spel.ast; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.expression.PropertyAccessor; +import org.springframework.expression.spel.ExpressionState; + +/** + * Utilities methods for use in the Ast classes. + * + * @author Andy Clement + * @since 3.0.2 + */ +public class AstUtils { + + /** + * Determines the set of property resolvers that should be used to try and access a property on the specified target + * type. The resolvers are considered to be in an ordered list, however in the returned list any that are exact + * matches for the input target type (as opposed to 'general' resolvers that could work for any type) are placed at + * the start of the list. In addition, there are specific resolvers that exactly name the class in question and + * resolvers that name a specific class but it is a supertype of the class we have. These are put at the end of the + * specific resolvers set and will be tried after exactly matching accessors but before generic accessors. + * + * @param targetType the type upon which property access is being attempted + * @return a list of resolvers that should be tried in order to access the property + */ + public static List<PropertyAccessor> getPropertyAccessorsToTry(Class<?> targetType, ExpressionState state) { + List<PropertyAccessor> specificAccessors = new ArrayList<PropertyAccessor>(); + List<PropertyAccessor> generalAccessors = new ArrayList<PropertyAccessor>(); + for (PropertyAccessor resolver : state.getPropertyAccessors()) { + Class<?>[] targets = resolver.getSpecificTargetClasses(); + if (targets == null) { // generic resolver that says it can be used for any type + generalAccessors.add(resolver); + } + else { + if (targetType != null) { + int pos = 0; + for (Class<?> clazz : targets) { + if (clazz == targetType) { // put exact matches on the front to be tried first? + specificAccessors.add(pos++, resolver); + } + else if (clazz.isAssignableFrom(targetType)) { // put supertype matches at the end of the + // specificAccessor list + generalAccessors.add(resolver); + } + } + } + } + } + List<PropertyAccessor> resolvers = new ArrayList<PropertyAccessor>(); + resolvers.addAll(specificAccessors); + resolvers.addAll(generalAccessors); + return resolvers; + } +} diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/FormatHelper.java b/org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/FormatHelper.java index f0af0bbbb1d..3983c207a2e 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/FormatHelper.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/FormatHelper.java @@ -1,84 +1,84 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.expression.spel.ast; - -import java.util.List; - -import org.springframework.core.convert.TypeDescriptor; - -/** - * Utility methods (formatters, etc) used during parsing and evaluation. - * - * @author Andy Clement - */ -public class FormatHelper { - - /** - * Produce a nice string for a given method name with specified arguments. - * @param name the name of the method - * @param argumentTypes the types of the arguments to the method - * @return nicely formatted string, eg. foo(String,int) - */ - public static String formatMethodForMessage(String name, List<TypeDescriptor> argumentTypes) { - StringBuilder sb = new StringBuilder(); - sb.append(name); - sb.append("("); - for (int i = 0; i < argumentTypes.size(); i++) { - if (i > 0) { - sb.append(","); - } - TypeDescriptor typeDescriptor = argumentTypes.get(i); - if (typeDescriptor != null) { - sb.append(formatClassNameForMessage(typeDescriptor.getType())); - } - else { - sb.append(formatClassNameForMessage(null)); - } - } - sb.append(")"); - return sb.toString(); - } - - /** - * Produce a nice string for a given class object. - * For example, a string array will have the formatted name "java.lang.String[]". - * @param clazz The class whose name is to be formatted - * @return a formatted string suitable for message inclusion - */ - public static String formatClassNameForMessage(Class<?> clazz) { - if (clazz == null) { - return "null"; - } - StringBuilder fmtd = new StringBuilder(); - if (clazz.isArray()) { - int dims = 1; - Class baseClass = clazz.getComponentType(); - while (baseClass.isArray()) { - baseClass = baseClass.getComponentType(); - dims++; - } - fmtd.append(baseClass.getName()); - for (int i = 0; i < dims; i++) { - fmtd.append("[]"); - } - } else { - fmtd.append(clazz.getName()); - } - return fmtd.toString(); - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.expression.spel.ast; + +import java.util.List; + +import org.springframework.core.convert.TypeDescriptor; + +/** + * Utility methods (formatters, etc) used during parsing and evaluation. + * + * @author Andy Clement + */ +public class FormatHelper { + + /** + * Produce a nice string for a given method name with specified arguments. + * @param name the name of the method + * @param argumentTypes the types of the arguments to the method + * @return nicely formatted string, eg. foo(String,int) + */ + public static String formatMethodForMessage(String name, List<TypeDescriptor> argumentTypes) { + StringBuilder sb = new StringBuilder(); + sb.append(name); + sb.append("("); + for (int i = 0; i < argumentTypes.size(); i++) { + if (i > 0) { + sb.append(","); + } + TypeDescriptor typeDescriptor = argumentTypes.get(i); + if (typeDescriptor != null) { + sb.append(formatClassNameForMessage(typeDescriptor.getType())); + } + else { + sb.append(formatClassNameForMessage(null)); + } + } + sb.append(")"); + return sb.toString(); + } + + /** + * Produce a nice string for a given class object. + * For example, a string array will have the formatted name "java.lang.String[]". + * @param clazz The class whose name is to be formatted + * @return a formatted string suitable for message inclusion + */ + public static String formatClassNameForMessage(Class<?> clazz) { + if (clazz == null) { + return "null"; + } + StringBuilder fmtd = new StringBuilder(); + if (clazz.isArray()) { + int dims = 1; + Class baseClass = clazz.getComponentType(); + while (baseClass.isArray()) { + baseClass = baseClass.getComponentType(); + dims++; + } + fmtd.append(baseClass.getName()); + for (int i = 0; i < dims; i++) { + fmtd.append("[]"); + } + } else { + fmtd.append(clazz.getName()); + } + return fmtd.toString(); + } + +} diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/InlineList.java b/org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/InlineList.java index a5a818a3b27..ad7bf42a84c 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/InlineList.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/InlineList.java @@ -1,120 +1,120 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.expression.spel.ast; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.springframework.expression.EvaluationException; -import org.springframework.expression.TypedValue; -import org.springframework.expression.spel.ExpressionState; -import org.springframework.expression.spel.SpelNode; - -/** - * Represent a list in an expression, e.g. '{1,2,3}' - * - * @author Andy Clement - * @since 3.0.4 - */ -public class InlineList extends SpelNodeImpl { - - // if the list is purely literals, it is a constant value and can be computed and cached - TypedValue constant = null; // TODO must be immutable list - - public InlineList(int pos, SpelNodeImpl... args) { - super(pos, args); - checkIfConstant(); - } - - /** - * If all the components of the list are constants, or lists that themselves contain constants, then a constant list - * can be built to represent this node. This will speed up later getValue calls and reduce the amount of garbage - * created. - */ - private void checkIfConstant() { - boolean isConstant = true; - for (int c = 0, max = getChildCount(); c < max; c++) { - SpelNode child = getChild(c); - if (!(child instanceof Literal)) { - if (child instanceof InlineList) { - InlineList inlineList = (InlineList) child; - if (!inlineList.isConstant()) { - isConstant = false; - } - } else { - isConstant = false; - } - } - } - if (isConstant) { - List<Object> constantList = new ArrayList<Object>(); - int childcount = getChildCount(); - for (int c = 0; c < childcount; c++) { - SpelNode child = getChild(c); - if ((child instanceof Literal)) { - constantList.add(((Literal) child).getLiteralValue().getValue()); - } else if (child instanceof InlineList) { - constantList.add(((InlineList) child).getConstantValue()); - } - } - this.constant = new TypedValue(Collections.unmodifiableList(constantList)); - } - } - - @Override - public TypedValue getValueInternal(ExpressionState expressionState) throws EvaluationException { - if (constant != null) { - return constant; - } else { - List<Object> returnValue = new ArrayList<Object>(); - int childcount = getChildCount(); - for (int c = 0; c < childcount; c++) { - returnValue.add(getChild(c).getValue(expressionState)); - } - return new TypedValue(returnValue); - } - } - - @Override - public String toStringAST() { - StringBuilder s = new StringBuilder(); - // string ast matches input string, not the 'toString()' of the resultant collection, which would use [] - s.append('{'); - int count = getChildCount(); - for (int c = 0; c < count; c++) { - if (c > 0) { - s.append(','); - } - s.append(getChild(c).toStringAST()); - } - s.append('}'); - return s.toString(); - } - - /** - * @return whether this list is a constant value - */ - public boolean isConstant() { - return constant != null; - } - - @SuppressWarnings("unchecked") - private List<Object> getConstantValue() { - return (List<Object>) constant.getValue(); - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.expression.spel.ast; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.springframework.expression.EvaluationException; +import org.springframework.expression.TypedValue; +import org.springframework.expression.spel.ExpressionState; +import org.springframework.expression.spel.SpelNode; + +/** + * Represent a list in an expression, e.g. '{1,2,3}' + * + * @author Andy Clement + * @since 3.0.4 + */ +public class InlineList extends SpelNodeImpl { + + // if the list is purely literals, it is a constant value and can be computed and cached + TypedValue constant = null; // TODO must be immutable list + + public InlineList(int pos, SpelNodeImpl... args) { + super(pos, args); + checkIfConstant(); + } + + /** + * If all the components of the list are constants, or lists that themselves contain constants, then a constant list + * can be built to represent this node. This will speed up later getValue calls and reduce the amount of garbage + * created. + */ + private void checkIfConstant() { + boolean isConstant = true; + for (int c = 0, max = getChildCount(); c < max; c++) { + SpelNode child = getChild(c); + if (!(child instanceof Literal)) { + if (child instanceof InlineList) { + InlineList inlineList = (InlineList) child; + if (!inlineList.isConstant()) { + isConstant = false; + } + } else { + isConstant = false; + } + } + } + if (isConstant) { + List<Object> constantList = new ArrayList<Object>(); + int childcount = getChildCount(); + for (int c = 0; c < childcount; c++) { + SpelNode child = getChild(c); + if ((child instanceof Literal)) { + constantList.add(((Literal) child).getLiteralValue().getValue()); + } else if (child instanceof InlineList) { + constantList.add(((InlineList) child).getConstantValue()); + } + } + this.constant = new TypedValue(Collections.unmodifiableList(constantList)); + } + } + + @Override + public TypedValue getValueInternal(ExpressionState expressionState) throws EvaluationException { + if (constant != null) { + return constant; + } else { + List<Object> returnValue = new ArrayList<Object>(); + int childcount = getChildCount(); + for (int c = 0; c < childcount; c++) { + returnValue.add(getChild(c).getValue(expressionState)); + } + return new TypedValue(returnValue); + } + } + + @Override + public String toStringAST() { + StringBuilder s = new StringBuilder(); + // string ast matches input string, not the 'toString()' of the resultant collection, which would use [] + s.append('{'); + int count = getChildCount(); + for (int c = 0; c < count; c++) { + if (c > 0) { + s.append(','); + } + s.append(getChild(c).toStringAST()); + } + s.append('}'); + return s.toString(); + } + + /** + * @return whether this list is a constant value + */ + public boolean isConstant() { + return constant != null; + } + + @SuppressWarnings("unchecked") + private List<Object> getConstantValue() { + return (List<Object>) constant.getValue(); + } + +} diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/IntLiteral.java b/org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/IntLiteral.java index 51ca0c385f7..15dc80d2dbc 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/IntLiteral.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/IntLiteral.java @@ -1,40 +1,40 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.expression.spel.ast; - -import org.springframework.expression.TypedValue; - -/** - * Expression language AST node that represents an integer literal. - * - * @author Andy Clement - * @since 3.0 - */ -public class IntLiteral extends Literal { - - private final TypedValue value; - - IntLiteral(String payload, int pos, int value) { - super(payload, pos); - this.value = new TypedValue(value); - } - - @Override - public TypedValue getLiteralValue() { - return this.value; - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.expression.spel.ast; + +import org.springframework.expression.TypedValue; + +/** + * Expression language AST node that represents an integer literal. + * + * @author Andy Clement + * @since 3.0 + */ +public class IntLiteral extends Literal { + + private final TypedValue value; + + IntLiteral(String payload, int pos, int value) { + super(payload, pos); + this.value = new TypedValue(value); + } + + @Override + public TypedValue getLiteralValue() { + return this.value; + } + +} diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/TypeCode.java b/org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/TypeCode.java index 124a74752d2..aeb7ca1cc6f 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/TypeCode.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/TypeCode.java @@ -1,61 +1,61 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.expression.spel.ast; - -/** - * Captures primitive types and their corresponding class objects, plus one special entry that represents all reference - * (non-primitive) types. - * - * @author Andy Clement - */ -public enum TypeCode { - - OBJECT(Object.class), BOOLEAN(Boolean.TYPE), BYTE(Byte.TYPE), CHAR(Character.TYPE), // - SHORT(Short.TYPE), INT(Integer.TYPE), LONG(Long.TYPE), FLOAT(Float.TYPE), DOUBLE(Double.TYPE); - - private Class<?> type; - - TypeCode(Class<?> type) { - this.type = type; - } - - public Class<?> getType() { - return type; - } - - public static TypeCode forName(String name) { - String searchingFor = name.toUpperCase(); - TypeCode[] tcs = values(); - for (int i = 1; i < tcs.length; i++) { - if (tcs[i].name().equals(searchingFor)) { - return tcs[i]; - } - } - return TypeCode.OBJECT; - } - - public static TypeCode forClass(Class<?> c) { - TypeCode[] allValues = TypeCode.values(); - for (int i = 0; i < allValues.length; i++) { - TypeCode typeCode = allValues[i]; - if (c == typeCode.getType()) { - return typeCode; - } - } - return OBJECT; - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.expression.spel.ast; + +/** + * Captures primitive types and their corresponding class objects, plus one special entry that represents all reference + * (non-primitive) types. + * + * @author Andy Clement + */ +public enum TypeCode { + + OBJECT(Object.class), BOOLEAN(Boolean.TYPE), BYTE(Byte.TYPE), CHAR(Character.TYPE), // + SHORT(Short.TYPE), INT(Integer.TYPE), LONG(Long.TYPE), FLOAT(Float.TYPE), DOUBLE(Double.TYPE); + + private Class<?> type; + + TypeCode(Class<?> type) { + this.type = type; + } + + public Class<?> getType() { + return type; + } + + public static TypeCode forName(String name) { + String searchingFor = name.toUpperCase(); + TypeCode[] tcs = values(); + for (int i = 1; i < tcs.length; i++) { + if (tcs[i].name().equals(searchingFor)) { + return tcs[i]; + } + } + return TypeCode.OBJECT; + } + + public static TypeCode forClass(Class<?> c) { + TypeCode[] allValues = TypeCode.values(); + for (int i = 0; i < allValues.length; i++) { + TypeCode typeCode = allValues[i]; + if (c == typeCode.getType()) { + return typeCode; + } + } + return OBJECT; + } + +} diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/spel/generated/SpringExpressions.g b/org.springframework.expression/src/main/java/org/springframework/expression/spel/generated/SpringExpressions.g index fd53c878d8b..82a5f4a8b92 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/spel/generated/SpringExpressions.g +++ b/org.springframework.expression/src/main/java/org/springframework/expression/spel/generated/SpringExpressions.g @@ -1,268 +1,268 @@ -grammar SpringExpressions; - -options { - language = Java; - output=AST; - k=2; -} - -tokens { - INTEGER_LITERAL; - EXPRESSION; - QUALIFIED_IDENTIFIER; - PROPERTY_OR_FIELD; - INDEXER; - CONSTRUCTOR; - HOLDER; - NAMED_ARGUMENT; - FUNCTIONREF; - TYPEREF; - VARIABLEREF; - METHOD; - ADD; - SUBTRACT; - NUMBER; -} - -// applies only to the parser: -@header {package org.springframework.expression.spel.generated;} - -// applies only to the lexer: -@lexer::header {package org.springframework.expression.spel.generated;} - -@members { - // For collecting info whilst processing rules that can be used in messages - protected Stack<String> paraphrase = new Stack<String>(); -} - -@rulecatch { - catch(RecognitionException e) { - reportError(e); - throw e; - } -} - -expr: expression EOF!; - -expression : - logicalOrExpression - ( (ASSIGN^ logicalOrExpression) - | (DEFAULT^ logicalOrExpression) - | (QMARK^ expression COLON! expression))?; - -parenExpr : LPAREN! expression RPAREN!; - -logicalOrExpression -: logicalAndExpression (OR^ logicalAndExpression)*; - -logicalAndExpression -: relationalExpression (AND^ relationalExpression)*; - -relationalExpression : sumExpression (relationalOperator^ sumExpression)?; - -sumExpression - : productExpression ( (PLUS^ | MINUS^) productExpression)*; - -productExpression - : powerExpr ((STAR^ | DIV^| MOD^) powerExpr)* ; - -powerExpr : unaryExpression (POWER^ unaryExpression)? ; - -unaryExpression - : (PLUS^ | MINUS^ | BANG^) unaryExpression - | primaryExpression ; - -primaryExpression - : startNode (node)? -> ^(EXPRESSION startNode (node)?); - -startNode - : - parenExpr - | methodOrProperty - | functionOrVar - | indexer - | literal - | type - | constructor - | projection - | selection - | firstSelection - | lastSelection - ; - -node - : ((DOT dottedNode) | nonDottedNode)+; - -nonDottedNode - : indexer; - -dottedNode - : - ((methodOrProperty - | functionOrVar - | projection - | selection - | firstSelection - | lastSelection - )) - ; - -functionOrVar - : (POUND ID LPAREN) => function - | var - ; - -function : POUND id=ID methodArgs -> ^(FUNCTIONREF[$id] methodArgs); - -var : POUND id=ID -> ^(VARIABLEREF[$id]); - - -methodOrProperty - : (ID LPAREN) => id=ID methodArgs -> ^(METHOD[$id] methodArgs) - | property - ; - -// may have to preserve these commas to make it easier to offer suggestions in the right place -// mod at 9th feb 19:13 - added the second 'COMMA?' to allow for code completion "foo(A," -// TODO need to preserve commas and then check for badly formed call later (optimizing tree walk) to disallow "foo(a,b,c,)" -methodArgs : LPAREN! (argument (COMMA! argument)* (COMMA!)?)? RPAREN!; - -// If we match ID then create a node called PROPERTY_OR_FIELD and copy the id info into it. -// this means the propertyOrField.text is what id.text would have been, rather than having to -// access id as a child of the new node. -property: id=ID -> ^(PROPERTY_OR_FIELD[$id]); - - -indexer: LBRACKET r1=argument (COMMA r2=argument)* RBRACKET -> ^(INDEXER $r1 ($r2)*); - -// argument; - // TODO make expression conditional with ? if want completion for when the RCURLY is missing -projection: PROJECT^ expression RBRACKET!; - -selection: SELECT^ expression RBRACKET!; - -firstSelection: SELECT_FIRST^ expression RBRACKET!; - -lastSelection: SELECT_LAST^ expression RBRACKET!; - -// TODO cope with array types -type: TYPE qualifiedId RPAREN -> ^(TYPEREF qualifiedId); -//type: TYPE tn=qualifiedId (LBRACKET RBRACKET)? (COMMA qid=qualifiedId)? RPAREN - - -constructor - : ('new' qualifiedId LPAREN) => 'new' qualifiedId ctorArgs -> ^(CONSTRUCTOR qualifiedId ctorArgs) - ; - -ctorArgs - : LPAREN! (namedArgument (COMMA! namedArgument)*)? RPAREN!; - -argument : expression; - -namedArgument - : (ID ASSIGN) => id=ID ASSIGN expression - -> ^(NAMED_ARGUMENT[$id] expression) - | argument ; - -qualifiedId : ID (DOT ID)* -> ^(QUALIFIED_IDENTIFIER ID*); - -contextName : ID (DIV ID)* -> ^(QUALIFIED_IDENTIFIER ID*); - -literal - : INTEGER_LITERAL - | STRING_LITERAL - | DQ_STRING_LITERAL - | boolLiteral - | NULL_LITERAL - | HEXADECIMAL_INTEGER_LITERAL - | REAL_LITERAL - ; - -boolLiteral: TRUE | FALSE; - -INTEGER_LITERAL - : (DECIMAL_DIGIT)+ (INTEGER_TYPE_SUFFIX)?; - -HEXADECIMAL_INTEGER_LITERAL : ('0x' | '0X') (HEX_DIGIT)+ (INTEGER_TYPE_SUFFIX)?; - -relationalOperator - : EQUAL - | NOT_EQUAL - | LESS_THAN - | LESS_THAN_OR_EQUAL - | GREATER_THAN - | GREATER_THAN_OR_EQUAL - | INSTANCEOF - | BETWEEN - | MATCHES - ; - -ASSIGN: '='; -EQUAL: '=='; -NOT_EQUAL: '!='; -LESS_THAN: '<'; -LESS_THAN_OR_EQUAL: '<='; -GREATER_THAN: '>'; -GREATER_THAN_OR_EQUAL: '>='; -INSTANCEOF: 'instanceof'; -BETWEEN:'between'; -MATCHES:'matches'; -NULL_LITERAL: 'null'; - -SEMI: ';'; -DOT: '.'; -COMMA: ','; -LPAREN: '('; -RPAREN: ')'; -LCURLY: '{'; -RCURLY: '}'; -LBRACKET: '['; -RBRACKET: ']'; -PIPE: '|'; - -AND: 'and'; -OR: 'or'; -FALSE: 'false'; -TRUE: 'true'; - -PLUS: '+'; -MINUS: '-'; -DIV: '/'; -STAR: '*'; -MOD: '%'; -POWER: '^'; -BANG: '!'; -POUND: '#'; -QMARK: '?'; -DEFAULT: '??'; -PROJECT: '!['; -SELECT: '?['; -SELECT_FIRST: '^['; -SELECT_LAST: '$['; -TYPE: 'T('; - -STRING_LITERAL: '\''! (APOS|~'\'')* '\''!; -DQ_STRING_LITERAL: '"'! (~'"')* '"'!; -ID: ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_'|'0'..'9'|DOT_ESCAPED)*; -DOT_ESCAPED: '\\.'; -WS: ( ' ' | '\t' | '\n' |'\r')+ { $channel=HIDDEN; } ; -DOLLAR: '$'; -AT: '@'; -UPTO: '..'; -COLON: ':'; - - -REAL_LITERAL : - ('.' (DECIMAL_DIGIT)+ (EXPONENT_PART)? (REAL_TYPE_SUFFIX)?) | - ((DECIMAL_DIGIT)+ '.' (DECIMAL_DIGIT)+ (EXPONENT_PART)? (REAL_TYPE_SUFFIX)?) | - ((DECIMAL_DIGIT)+ (EXPONENT_PART) (REAL_TYPE_SUFFIX)?) | - ((DECIMAL_DIGIT)+ (REAL_TYPE_SUFFIX)); - -fragment APOS : '\''! '\''; -fragment DECIMAL_DIGIT : '0'..'9' ; -fragment INTEGER_TYPE_SUFFIX : ( 'L' | 'l' ); -fragment HEX_DIGIT : '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9'|'A'|'B'|'C'|'D'|'E'|'F'|'a'|'b'|'c'|'d'|'e'|'f'; - -fragment EXPONENT_PART : 'e' (SIGN)* (DECIMAL_DIGIT)+ | 'E' (SIGN)* (DECIMAL_DIGIT)+ ; -fragment SIGN : '+' | '-' ; -fragment REAL_TYPE_SUFFIX : 'F' | 'f' | 'D' | 'd'; +grammar SpringExpressions; + +options { + language = Java; + output=AST; + k=2; +} + +tokens { + INTEGER_LITERAL; + EXPRESSION; + QUALIFIED_IDENTIFIER; + PROPERTY_OR_FIELD; + INDEXER; + CONSTRUCTOR; + HOLDER; + NAMED_ARGUMENT; + FUNCTIONREF; + TYPEREF; + VARIABLEREF; + METHOD; + ADD; + SUBTRACT; + NUMBER; +} + +// applies only to the parser: +@header {package org.springframework.expression.spel.generated;} + +// applies only to the lexer: +@lexer::header {package org.springframework.expression.spel.generated;} + +@members { + // For collecting info whilst processing rules that can be used in messages + protected Stack<String> paraphrase = new Stack<String>(); +} + +@rulecatch { + catch(RecognitionException e) { + reportError(e); + throw e; + } +} + +expr: expression EOF!; + +expression : + logicalOrExpression + ( (ASSIGN^ logicalOrExpression) + | (DEFAULT^ logicalOrExpression) + | (QMARK^ expression COLON! expression))?; + +parenExpr : LPAREN! expression RPAREN!; + +logicalOrExpression +: logicalAndExpression (OR^ logicalAndExpression)*; + +logicalAndExpression +: relationalExpression (AND^ relationalExpression)*; + +relationalExpression : sumExpression (relationalOperator^ sumExpression)?; + +sumExpression + : productExpression ( (PLUS^ | MINUS^) productExpression)*; + +productExpression + : powerExpr ((STAR^ | DIV^| MOD^) powerExpr)* ; + +powerExpr : unaryExpression (POWER^ unaryExpression)? ; + +unaryExpression + : (PLUS^ | MINUS^ | BANG^) unaryExpression + | primaryExpression ; + +primaryExpression + : startNode (node)? -> ^(EXPRESSION startNode (node)?); + +startNode + : + parenExpr + | methodOrProperty + | functionOrVar + | indexer + | literal + | type + | constructor + | projection + | selection + | firstSelection + | lastSelection + ; + +node + : ((DOT dottedNode) | nonDottedNode)+; + +nonDottedNode + : indexer; + +dottedNode + : + ((methodOrProperty + | functionOrVar + | projection + | selection + | firstSelection + | lastSelection + )) + ; + +functionOrVar + : (POUND ID LPAREN) => function + | var + ; + +function : POUND id=ID methodArgs -> ^(FUNCTIONREF[$id] methodArgs); + +var : POUND id=ID -> ^(VARIABLEREF[$id]); + + +methodOrProperty + : (ID LPAREN) => id=ID methodArgs -> ^(METHOD[$id] methodArgs) + | property + ; + +// may have to preserve these commas to make it easier to offer suggestions in the right place +// mod at 9th feb 19:13 - added the second 'COMMA?' to allow for code completion "foo(A," +// TODO need to preserve commas and then check for badly formed call later (optimizing tree walk) to disallow "foo(a,b,c,)" +methodArgs : LPAREN! (argument (COMMA! argument)* (COMMA!)?)? RPAREN!; + +// If we match ID then create a node called PROPERTY_OR_FIELD and copy the id info into it. +// this means the propertyOrField.text is what id.text would have been, rather than having to +// access id as a child of the new node. +property: id=ID -> ^(PROPERTY_OR_FIELD[$id]); + + +indexer: LBRACKET r1=argument (COMMA r2=argument)* RBRACKET -> ^(INDEXER $r1 ($r2)*); + +// argument; + // TODO make expression conditional with ? if want completion for when the RCURLY is missing +projection: PROJECT^ expression RBRACKET!; + +selection: SELECT^ expression RBRACKET!; + +firstSelection: SELECT_FIRST^ expression RBRACKET!; + +lastSelection: SELECT_LAST^ expression RBRACKET!; + +// TODO cope with array types +type: TYPE qualifiedId RPAREN -> ^(TYPEREF qualifiedId); +//type: TYPE tn=qualifiedId (LBRACKET RBRACKET)? (COMMA qid=qualifiedId)? RPAREN + + +constructor + : ('new' qualifiedId LPAREN) => 'new' qualifiedId ctorArgs -> ^(CONSTRUCTOR qualifiedId ctorArgs) + ; + +ctorArgs + : LPAREN! (namedArgument (COMMA! namedArgument)*)? RPAREN!; + +argument : expression; + +namedArgument + : (ID ASSIGN) => id=ID ASSIGN expression + -> ^(NAMED_ARGUMENT[$id] expression) + | argument ; + +qualifiedId : ID (DOT ID)* -> ^(QUALIFIED_IDENTIFIER ID*); + +contextName : ID (DIV ID)* -> ^(QUALIFIED_IDENTIFIER ID*); + +literal + : INTEGER_LITERAL + | STRING_LITERAL + | DQ_STRING_LITERAL + | boolLiteral + | NULL_LITERAL + | HEXADECIMAL_INTEGER_LITERAL + | REAL_LITERAL + ; + +boolLiteral: TRUE | FALSE; + +INTEGER_LITERAL + : (DECIMAL_DIGIT)+ (INTEGER_TYPE_SUFFIX)?; + +HEXADECIMAL_INTEGER_LITERAL : ('0x' | '0X') (HEX_DIGIT)+ (INTEGER_TYPE_SUFFIX)?; + +relationalOperator + : EQUAL + | NOT_EQUAL + | LESS_THAN + | LESS_THAN_OR_EQUAL + | GREATER_THAN + | GREATER_THAN_OR_EQUAL + | INSTANCEOF + | BETWEEN + | MATCHES + ; + +ASSIGN: '='; +EQUAL: '=='; +NOT_EQUAL: '!='; +LESS_THAN: '<'; +LESS_THAN_OR_EQUAL: '<='; +GREATER_THAN: '>'; +GREATER_THAN_OR_EQUAL: '>='; +INSTANCEOF: 'instanceof'; +BETWEEN:'between'; +MATCHES:'matches'; +NULL_LITERAL: 'null'; + +SEMI: ';'; +DOT: '.'; +COMMA: ','; +LPAREN: '('; +RPAREN: ')'; +LCURLY: '{'; +RCURLY: '}'; +LBRACKET: '['; +RBRACKET: ']'; +PIPE: '|'; + +AND: 'and'; +OR: 'or'; +FALSE: 'false'; +TRUE: 'true'; + +PLUS: '+'; +MINUS: '-'; +DIV: '/'; +STAR: '*'; +MOD: '%'; +POWER: '^'; +BANG: '!'; +POUND: '#'; +QMARK: '?'; +DEFAULT: '??'; +PROJECT: '!['; +SELECT: '?['; +SELECT_FIRST: '^['; +SELECT_LAST: '$['; +TYPE: 'T('; + +STRING_LITERAL: '\''! (APOS|~'\'')* '\''!; +DQ_STRING_LITERAL: '"'! (~'"')* '"'!; +ID: ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_'|'0'..'9'|DOT_ESCAPED)*; +DOT_ESCAPED: '\\.'; +WS: ( ' ' | '\t' | '\n' |'\r')+ { $channel=HIDDEN; } ; +DOLLAR: '$'; +AT: '@'; +UPTO: '..'; +COLON: ':'; + + +REAL_LITERAL : + ('.' (DECIMAL_DIGIT)+ (EXPONENT_PART)? (REAL_TYPE_SUFFIX)?) | + ((DECIMAL_DIGIT)+ '.' (DECIMAL_DIGIT)+ (EXPONENT_PART)? (REAL_TYPE_SUFFIX)?) | + ((DECIMAL_DIGIT)+ (EXPONENT_PART) (REAL_TYPE_SUFFIX)?) | + ((DECIMAL_DIGIT)+ (REAL_TYPE_SUFFIX)); + +fragment APOS : '\''! '\''; +fragment DECIMAL_DIGIT : '0'..'9' ; +fragment INTEGER_TYPE_SUFFIX : ( 'L' | 'l' ); +fragment HEX_DIGIT : '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9'|'A'|'B'|'C'|'D'|'E'|'F'|'a'|'b'|'c'|'d'|'e'|'f'; + +fragment EXPONENT_PART : 'e' (SIGN)* (DECIMAL_DIGIT)+ | 'E' (SIGN)* (DECIMAL_DIGIT)+ ; +fragment SIGN : '+' | '-' ; +fragment REAL_TYPE_SUFFIX : 'F' | 'f' | 'D' | 'd'; diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/spel/standard/InternalSpelExpressionParser.java b/org.springframework.expression/src/main/java/org/springframework/expression/spel/standard/InternalSpelExpressionParser.java index 11a3cdbee8e..668e9e91a97 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/spel/standard/InternalSpelExpressionParser.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/spel/standard/InternalSpelExpressionParser.java @@ -1,850 +1,850 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.expression.spel.standard; - -import java.util.ArrayList; -import java.util.List; -import java.util.Stack; - -import org.springframework.expression.ParseException; -import org.springframework.expression.ParserContext; -import org.springframework.expression.common.TemplateAwareExpressionParser; -import org.springframework.expression.spel.InternalParseException; -import org.springframework.expression.spel.SpelMessage; -import org.springframework.expression.spel.SpelParseException; -import org.springframework.expression.spel.SpelParserConfiguration; -import org.springframework.expression.spel.ast.Assign; -import org.springframework.expression.spel.ast.BeanReference; -import org.springframework.expression.spel.ast.BooleanLiteral; -import org.springframework.expression.spel.ast.CompoundExpression; -import org.springframework.expression.spel.ast.ConstructorReference; -import org.springframework.expression.spel.ast.Elvis; -import org.springframework.expression.spel.ast.FunctionReference; -import org.springframework.expression.spel.ast.Identifier; -import org.springframework.expression.spel.ast.Indexer; -import org.springframework.expression.spel.ast.InlineList; -import org.springframework.expression.spel.ast.Literal; -import org.springframework.expression.spel.ast.MethodReference; -import org.springframework.expression.spel.ast.NullLiteral; -import org.springframework.expression.spel.ast.OpAnd; -import org.springframework.expression.spel.ast.OpDivide; -import org.springframework.expression.spel.ast.OpEQ; -import org.springframework.expression.spel.ast.OpGE; -import org.springframework.expression.spel.ast.OpGT; -import org.springframework.expression.spel.ast.OpLE; -import org.springframework.expression.spel.ast.OpLT; -import org.springframework.expression.spel.ast.OpMinus; -import org.springframework.expression.spel.ast.OpModulus; -import org.springframework.expression.spel.ast.OpMultiply; -import org.springframework.expression.spel.ast.OpNE; -import org.springframework.expression.spel.ast.OpOr; -import org.springframework.expression.spel.ast.OpPlus; -import org.springframework.expression.spel.ast.OperatorInstanceof; -import org.springframework.expression.spel.ast.OperatorMatches; -import org.springframework.expression.spel.ast.OperatorNot; -import org.springframework.expression.spel.ast.OperatorPower; -import org.springframework.expression.spel.ast.Projection; -import org.springframework.expression.spel.ast.PropertyOrFieldReference; -import org.springframework.expression.spel.ast.QualifiedIdentifier; -import org.springframework.expression.spel.ast.Selection; -import org.springframework.expression.spel.ast.SpelNodeImpl; -import org.springframework.expression.spel.ast.StringLiteral; -import org.springframework.expression.spel.ast.Ternary; -import org.springframework.expression.spel.ast.TypeReference; -import org.springframework.expression.spel.ast.VariableReference; -import org.springframework.util.Assert; - -/** - * Hand written SpEL parser. Instances are reusable but are not thread safe. - * - * @author Andy Clement - * @since 3.0 - */ -class InternalSpelExpressionParser extends TemplateAwareExpressionParser { - - // The expression being parsed - private String expressionString; - - // The token stream constructed from that expression string - private List<Token> tokenStream; - - // length of a populated token stream - private int tokenStreamLength; - - // Current location in the token stream when processing tokens - private int tokenStreamPointer; - - // For rules that build nodes, they are stacked here for return - private Stack<SpelNodeImpl> constructedNodes = new Stack<SpelNodeImpl>(); - - private SpelParserConfiguration configuration; - - - /** - * Create a parser with some configured behavior. - * @param configuration custom configuration options - */ - public InternalSpelExpressionParser(SpelParserConfiguration configuration) { - this.configuration = configuration; - } - - - @Override - protected SpelExpression doParseExpression(String expressionString, ParserContext context) throws ParseException { - try { - this.expressionString = expressionString; - Tokenizer tokenizer = new Tokenizer(expressionString); - tokenizer.process(); - tokenStream = tokenizer.getTokens(); - tokenStreamLength = tokenStream.size(); - tokenStreamPointer = 0; - constructedNodes.clear(); - SpelNodeImpl ast = eatExpression(); - if (moreTokens()) { - throw new SpelParseException(peekToken().startpos,SpelMessage.MORE_INPUT,toString(nextToken())); - } - Assert.isTrue(constructedNodes.isEmpty()); - return new SpelExpression(expressionString, ast, configuration); - } - catch (InternalParseException ipe) { - throw ipe.getCause(); - } - } - - // expression - // : logicalOrExpression - // ( (ASSIGN^ logicalOrExpression) - // | (DEFAULT^ logicalOrExpression) - // | (QMARK^ expression COLON! expression) - // | (ELVIS^ expression))?; - private SpelNodeImpl eatExpression() { - SpelNodeImpl expr = eatLogicalOrExpression(); - if (moreTokens()) { - Token t = peekToken(); - if (t.kind==TokenKind.ASSIGN) { // a=b - if (expr==null) { - expr = new NullLiteral(toPos(t.startpos-1,t.endpos-1)); - } - nextToken(); - SpelNodeImpl assignedValue = eatLogicalOrExpression(); - return new Assign(toPos(t),expr,assignedValue); - } else if (t.kind==TokenKind.ELVIS) { // a?:b (a if it isn't null, otherwise b) - if (expr==null) { - expr = new NullLiteral(toPos(t.startpos-1,t.endpos-2)); - } - nextToken(); // elvis has left the building - SpelNodeImpl valueIfNull = eatExpression(); - if (valueIfNull==null) { - valueIfNull = new NullLiteral(toPos(t.startpos+1,t.endpos+1)); - } - return new Elvis(toPos(t),expr,valueIfNull); - } else if (t.kind==TokenKind.QMARK) { // a?b:c - if (expr==null) { - expr = new NullLiteral(toPos(t.startpos-1,t.endpos-1)); - } - nextToken(); - SpelNodeImpl ifTrueExprValue = eatExpression(); - eatToken(TokenKind.COLON); - SpelNodeImpl ifFalseExprValue = eatExpression(); - return new Ternary(toPos(t),expr,ifTrueExprValue,ifFalseExprValue); - } - } - return expr; - } - - //logicalOrExpression : logicalAndExpression (OR^ logicalAndExpression)*; - private SpelNodeImpl eatLogicalOrExpression() { - SpelNodeImpl expr = eatLogicalAndExpression(); - while (peekIdentifierToken("or")) { - Token t = nextToken(); //consume OR - SpelNodeImpl rhExpr = eatLogicalAndExpression(); - checkRightOperand(t,rhExpr); - expr = new OpOr(toPos(t),expr,rhExpr); - } - return expr; - } - - // logicalAndExpression : relationalExpression (AND^ relationalExpression)*; - private SpelNodeImpl eatLogicalAndExpression() { - SpelNodeImpl expr = eatRelationalExpression(); - while (peekIdentifierToken("and")) { - Token t = nextToken();// consume 'AND' - SpelNodeImpl rhExpr = eatRelationalExpression(); - checkRightOperand(t,rhExpr); - expr = new OpAnd(toPos(t),expr,rhExpr); - } - return expr; - } - - // relationalExpression : sumExpression (relationalOperator^ sumExpression)?; - private SpelNodeImpl eatRelationalExpression() { - SpelNodeImpl expr = eatSumExpression(); - Token relationalOperatorToken = maybeEatRelationalOperator(); - if (relationalOperatorToken != null) { - Token t = nextToken(); //consume relational operator token - SpelNodeImpl rhExpr = eatSumExpression(); - checkRightOperand(t,rhExpr); - TokenKind tk = relationalOperatorToken.kind; - if (relationalOperatorToken.isNumericRelationalOperator()) { - int pos = toPos(t); - if (tk==TokenKind.GT) { - return new OpGT(pos,expr,rhExpr); - } else if (tk==TokenKind.LT) { - return new OpLT(pos,expr,rhExpr); - } else if (tk==TokenKind.LE) { - return new OpLE(pos,expr,rhExpr); - } else if (tk==TokenKind.GE) { - return new OpGE(pos,expr,rhExpr); - } else if (tk == TokenKind.EQ) { - return new OpEQ(pos,expr,rhExpr); - } else { - Assert.isTrue(tk == TokenKind.NE); - return new OpNE(pos,expr,rhExpr); - } - } - if (tk==TokenKind.INSTANCEOF) { - return new OperatorInstanceof(toPos(t),expr,rhExpr); - } else if (tk==TokenKind.MATCHES) { - return new OperatorMatches(toPos(t),expr,rhExpr); - } else { - Assert.isTrue(tk==TokenKind.BETWEEN); - return new org.springframework.expression.spel.ast.OperatorBetween(toPos(t),expr,rhExpr); - } - } - return expr; - } - - //sumExpression: productExpression ( (PLUS^ | MINUS^) productExpression)*; - private SpelNodeImpl eatSumExpression() { - SpelNodeImpl expr = eatProductExpression(); - while (peekToken(TokenKind.PLUS,TokenKind.MINUS)) { - Token t = nextToken();//consume PLUS or MINUS - SpelNodeImpl rhExpr = eatProductExpression(); - checkRightOperand(t,rhExpr); - if (t.kind==TokenKind.PLUS) { - expr = new OpPlus(toPos(t),expr,rhExpr); - } else { - Assert.isTrue(t.kind==TokenKind.MINUS); - expr = new OpMinus(toPos(t),expr,rhExpr); - } - } - return expr; - } - - // productExpression: powerExpr ((STAR^ | DIV^| MOD^) powerExpr)* ; - private SpelNodeImpl eatProductExpression() { - SpelNodeImpl expr = eatPowerExpression(); - while (peekToken(TokenKind.STAR,TokenKind.DIV,TokenKind.MOD)) { - Token t = nextToken(); // consume STAR/DIV/MOD - SpelNodeImpl rhExpr = eatPowerExpression(); - checkRightOperand(t,rhExpr); - if (t.kind==TokenKind.STAR) { - expr = new OpMultiply(toPos(t),expr,rhExpr); - } else if (t.kind==TokenKind.DIV) { - expr = new OpDivide(toPos(t),expr,rhExpr); - } else { - Assert.isTrue(t.kind==TokenKind.MOD); - expr = new OpModulus(toPos(t),expr,rhExpr); - } - } - return expr; - } - - // powerExpr : unaryExpression (POWER^ unaryExpression)? ; - private SpelNodeImpl eatPowerExpression() { - SpelNodeImpl expr = eatUnaryExpression(); - if (peekToken(TokenKind.POWER)) { - Token t = nextToken();//consume POWER - SpelNodeImpl rhExpr = eatUnaryExpression(); - checkRightOperand(t,rhExpr); - return new OperatorPower(toPos(t),expr, rhExpr); - } - return expr; - } - - // unaryExpression: (PLUS^ | MINUS^ | BANG^) unaryExpression | primaryExpression ; - private SpelNodeImpl eatUnaryExpression() { - if (peekToken(TokenKind.PLUS,TokenKind.MINUS,TokenKind.NOT)) { - Token t = nextToken(); - SpelNodeImpl expr = eatUnaryExpression(); - if (t.kind==TokenKind.NOT) { - return new OperatorNot(toPos(t),expr); - } else if (t.kind==TokenKind.PLUS) { - return new OpPlus(toPos(t),expr); - } else { - Assert.isTrue(t.kind==TokenKind.MINUS); - return new OpMinus(toPos(t),expr); - } - } else { - return eatPrimaryExpression(); - } - } - - // primaryExpression : startNode (node)? -> ^(EXPRESSION startNode (node)?); - private SpelNodeImpl eatPrimaryExpression() { - List<SpelNodeImpl> nodes = new ArrayList<SpelNodeImpl>(); - SpelNodeImpl start = eatStartNode(); // always a start node - nodes.add(start); - while (maybeEatNode()) { - nodes.add(pop()); - } - if (nodes.size()==1) { - return nodes.get(0); - } else { - return new CompoundExpression(toPos(start.getStartPosition(),nodes.get(nodes.size()-1).getEndPosition()),nodes.toArray(new SpelNodeImpl[nodes.size()])); - } - } - - // node : ((DOT dottedNode) | (SAFE_NAVI dottedNode) | nonDottedNode)+; - private boolean maybeEatNode() { - SpelNodeImpl expr = null; - if (peekToken(TokenKind.DOT,TokenKind.SAFE_NAVI)) { - expr = eatDottedNode(); - } else { - expr = maybeEatNonDottedNode(); - } - if (expr==null) { - return false; - } else { - push(expr); - return true; - } - } - - // nonDottedNode: indexer; - private SpelNodeImpl maybeEatNonDottedNode() { - if (peekToken(TokenKind.LSQUARE)) { - if (maybeEatIndexer()) { - return pop(); - } - } - return null; - } - - //dottedNode - // : ((methodOrProperty - // | functionOrVar - // | projection - // | selection - // | firstSelection - // | lastSelection - // )) - // ; - private SpelNodeImpl eatDottedNode() { - Token t = nextToken();// it was a '.' or a '?.' - boolean nullSafeNavigation = t.kind==TokenKind.SAFE_NAVI; - if (maybeEatMethodOrProperty(nullSafeNavigation) || maybeEatFunctionOrVar() || maybeEatProjection(nullSafeNavigation) || maybeEatSelection(nullSafeNavigation)) { - return pop(); - } - if (peekToken()==null) { - // unexpectedly ran out of data - raiseInternalException(t.startpos,SpelMessage.OOD); - } else { - raiseInternalException(t.startpos,SpelMessage.UNEXPECTED_DATA_AFTER_DOT,toString(peekToken())); - } - return null; - } - - // functionOrVar - // : (POUND ID LPAREN) => function - // | var - // - // function : POUND id=ID methodArgs -> ^(FUNCTIONREF[$id] methodArgs); - // var : POUND id=ID -> ^(VARIABLEREF[$id]); - private boolean maybeEatFunctionOrVar() { - if (!peekToken(TokenKind.HASH)) { - return false; - } - Token t = nextToken(); - Token functionOrVariableName = eatToken(TokenKind.IDENTIFIER); - SpelNodeImpl[] args = maybeEatMethodArgs(); - if (args==null) { - push(new VariableReference(functionOrVariableName.data,toPos(t.startpos,functionOrVariableName.endpos))); - return true; - } else { - push(new FunctionReference(functionOrVariableName.data,toPos(t.startpos,functionOrVariableName.endpos),args)); - return true; - } - } - - // methodArgs : LPAREN! (argument (COMMA! argument)* (COMMA!)?)? RPAREN!; - private SpelNodeImpl[] maybeEatMethodArgs() { - if (!peekToken(TokenKind.LPAREN)) { - return null; - } - List<SpelNodeImpl> args = new ArrayList<SpelNodeImpl>(); - consumeArguments(args); - eatToken(TokenKind.RPAREN); - return args.toArray(new SpelNodeImpl[args.size()]); - } - - private void eatConstructorArgs(List<SpelNodeImpl> accumulatedArguments) { - if (!peekToken(TokenKind.LPAREN)) { - throw new InternalParseException(new SpelParseException(expressionString,positionOf(peekToken()),SpelMessage.MISSING_CONSTRUCTOR_ARGS)); - } - consumeArguments(accumulatedArguments); - eatToken(TokenKind.RPAREN); - } - - /** - * Used for consuming arguments for either a method or a constructor call - */ - private void consumeArguments(List<SpelNodeImpl> accumulatedArguments) { - int pos = peekToken().startpos; - Token next = null; - do { - nextToken();// consume ( (first time through) or comma (subsequent times) - Token t = peekToken(); - if (t==null) { - raiseInternalException(pos,SpelMessage.RUN_OUT_OF_ARGUMENTS); - } - if (t.kind!=TokenKind.RPAREN) { - accumulatedArguments.add(eatExpression()); - } - next = peekToken(); - } while (next!=null && next.kind==TokenKind.COMMA); - if (next==null) { - raiseInternalException(pos,SpelMessage.RUN_OUT_OF_ARGUMENTS); - } - } - - private int positionOf(Token t) { - if (t==null) { - // if null assume the problem is because the right token was - // not found at the end of the expression - return expressionString.length(); - } else { - return t.startpos; - } - } - - - //startNode - // : parenExpr | literal - // | type - // | methodOrProperty - // | functionOrVar - // | projection - // | selection - // | firstSelection - // | lastSelection - // | indexer - // | constructor - private SpelNodeImpl eatStartNode() { - if (maybeEatLiteral()) { - return pop(); - } else if (maybeEatParenExpression()) { - return pop(); - } else if (maybeEatTypeReference() || maybeEatNullReference() || maybeEatConstructorReference() || maybeEatMethodOrProperty(false) || maybeEatFunctionOrVar()) { - return pop(); - } else if (maybeEatBeanReference()) { - return pop(); - } else if (maybeEatProjection(false) || maybeEatSelection(false) || maybeEatIndexer()) { - return pop(); - } else if (maybeEatInlineList()) { - return pop(); - } else { - return null; - } - } - - // parse: @beanname @'bean.name' - // quoted if dotted - private boolean maybeEatBeanReference() { - if (peekToken(TokenKind.BEAN_REF)) { - Token beanRefToken = nextToken(); - Token beanNameToken = null; - String beanname = null; - if (peekToken(TokenKind.IDENTIFIER)) { - beanNameToken = eatToken(TokenKind.IDENTIFIER); - beanname = beanNameToken.data; - } else if (peekToken(TokenKind.LITERAL_STRING)) { - beanNameToken = eatToken(TokenKind.LITERAL_STRING); - beanname = beanNameToken.stringValue(); - beanname = beanname.substring(1, beanname.length() - 1); - } else { - raiseInternalException(beanRefToken.startpos,SpelMessage.INVALID_BEAN_REFERENCE); - } - - BeanReference beanReference = new BeanReference(toPos(beanNameToken),beanname); - constructedNodes.push(beanReference); - return true; - } - return false; - } - - private boolean maybeEatTypeReference() { - if (peekToken(TokenKind.IDENTIFIER)) { - Token typeName = peekToken(); - if (!typeName.stringValue().equals("T")) { - return false; - } - nextToken(); - eatToken(TokenKind.LPAREN); - SpelNodeImpl node = eatPossiblyQualifiedId(); - // dotted qualified id - eatToken(TokenKind.RPAREN); - constructedNodes.push(new TypeReference(toPos(typeName),node)); - return true; - } - return false; - } - - private boolean maybeEatNullReference() { - if (peekToken(TokenKind.IDENTIFIER)) { - Token nullToken = peekToken(); - if (!nullToken.stringValue().equals("null")) { - return false; - } - nextToken(); - constructedNodes.push(new NullLiteral(toPos(nullToken))); - return true; - } - return false; - } - - //projection: PROJECT^ expression RCURLY!; - private boolean maybeEatProjection(boolean nullSafeNavigation) { - Token t = peekToken(); - if (!peekToken(TokenKind.PROJECT,true)) { - return false; - } - SpelNodeImpl expr = eatExpression(); - eatToken(TokenKind.RSQUARE); - constructedNodes.push(new Projection(nullSafeNavigation, toPos(t), expr)); - return true; - } - - // list = LCURLY (element (COMMA element)*) RCURLY - private boolean maybeEatInlineList() { - Token t = peekToken(); - if (!peekToken(TokenKind.LCURLY,true)) { - return false; - } - SpelNodeImpl expr = null; - Token closingCurly = peekToken(); - if (peekToken(TokenKind.RCURLY,true)) { - // empty list '[]' - expr = new InlineList(toPos(t.startpos,closingCurly.endpos)); - } else { - List<SpelNodeImpl> listElements = new ArrayList<SpelNodeImpl>(); - do { - listElements.add(eatExpression()); - } while (peekToken(TokenKind.COMMA,true)); - closingCurly = eatToken(TokenKind.RCURLY); - expr = new InlineList(toPos(t.startpos,closingCurly.endpos),listElements.toArray(new SpelNodeImpl[listElements.size()])); - } - constructedNodes.push(expr); - return true; - } - - private boolean maybeEatIndexer() { - Token t = peekToken(); - if (!peekToken(TokenKind.LSQUARE,true)) { - return false; - } - SpelNodeImpl expr = eatExpression(); - eatToken(TokenKind.RSQUARE); - constructedNodes.push(new Indexer(toPos(t),expr)); - return true; - } - - private boolean maybeEatSelection(boolean nullSafeNavigation) { - Token t = peekToken(); - if (!peekSelectToken()) { - return false; - } - nextToken(); - SpelNodeImpl expr = eatExpression(); - eatToken(TokenKind.RSQUARE); - if (t.kind==TokenKind.SELECT_FIRST) { - constructedNodes.push(new Selection(nullSafeNavigation,Selection.FIRST,toPos(t),expr)); - } else if (t.kind==TokenKind.SELECT_LAST) { - constructedNodes.push(new Selection(nullSafeNavigation,Selection.LAST,toPos(t),expr)); - } else { - constructedNodes.push(new Selection(nullSafeNavigation,Selection.ALL,toPos(t),expr)); - } - return true; - } - - /** - * Eat an identifier, possibly qualified (meaning that it is dotted). - * TODO AndyC Could create complete identifiers (a.b.c) here rather than a sequence of them? (a, b, c) - */ - private SpelNodeImpl eatPossiblyQualifiedId() { - List<SpelNodeImpl> qualifiedIdPieces = new ArrayList<SpelNodeImpl>(); - Token startnode = eatToken(TokenKind.IDENTIFIER); - qualifiedIdPieces.add(new Identifier(startnode.stringValue(),toPos(startnode))); - while (peekToken(TokenKind.DOT,true)) { - Token node = eatToken(TokenKind.IDENTIFIER); - qualifiedIdPieces.add(new Identifier(node.stringValue(),toPos(node))); - } - return new QualifiedIdentifier(toPos(startnode.startpos,qualifiedIdPieces.get(qualifiedIdPieces.size()-1).getEndPosition()),qualifiedIdPieces.toArray(new SpelNodeImpl[qualifiedIdPieces.size()])); - } - - // This is complicated due to the support for dollars in identifiers. Dollars are normally separate tokens but - // there we want to combine a series of identifiers and dollars into a single identifier - private boolean maybeEatMethodOrProperty(boolean nullSafeNavigation) { - if (peekToken(TokenKind.IDENTIFIER)) { - Token methodOrPropertyName = nextToken(); - SpelNodeImpl[] args = maybeEatMethodArgs(); - if (args==null) { - // property - push(new PropertyOrFieldReference(nullSafeNavigation, methodOrPropertyName.data,toPos(methodOrPropertyName))); - return true; - } else { - // methodreference - push(new MethodReference(nullSafeNavigation, methodOrPropertyName.data,toPos(methodOrPropertyName),args)); - // TODO what is the end position for a method reference? the name or the last arg? - return true; - } - } - return false; - - } - - //constructor - //: ('new' qualifiedId LPAREN) => 'new' qualifiedId ctorArgs -> ^(CONSTRUCTOR qualifiedId ctorArgs) - private boolean maybeEatConstructorReference() { - if (peekIdentifierToken("new")) { - Token newToken = nextToken(); - SpelNodeImpl possiblyQualifiedConstructorName = eatPossiblyQualifiedId(); - List<SpelNodeImpl> nodes = new ArrayList<SpelNodeImpl>(); - nodes.add(possiblyQualifiedConstructorName); - if (peekToken(TokenKind.LSQUARE)) { - // array initializer - List<SpelNodeImpl> dimensions = new ArrayList<SpelNodeImpl>(); - while (peekToken(TokenKind.LSQUARE,true)) { - if (!peekToken(TokenKind.RSQUARE)) { - dimensions.add(eatExpression()); - } else { - dimensions.add(null); - } - eatToken(TokenKind.RSQUARE); - } - if (maybeEatInlineList()) { - nodes.add(pop()); - } - push(new ConstructorReference(toPos(newToken), dimensions.toArray(new SpelNodeImpl[dimensions.size()]), - nodes.toArray(new SpelNodeImpl[nodes.size()]))); - } else { - // regular constructor invocation - eatConstructorArgs(nodes); - // TODO correct end position? - push(new ConstructorReference(toPos(newToken), nodes.toArray(new SpelNodeImpl[nodes.size()]))); - } - return true; - } - return false; - } - - private void push(SpelNodeImpl newNode) { - constructedNodes.push(newNode); - } - - private SpelNodeImpl pop() { - return constructedNodes.pop(); - } - - // literal - // : INTEGER_LITERAL - // | boolLiteral - // | STRING_LITERAL - // | HEXADECIMAL_INTEGER_LITERAL - // | REAL_LITERAL - // | DQ_STRING_LITERAL - // | NULL_LITERAL - private boolean maybeEatLiteral() { - Token t = peekToken(); - if (t==null) { - return false; - } - if (t.kind==TokenKind.LITERAL_INT) { - push(Literal.getIntLiteral(t.data, toPos(t), 10)); - } else if (t.kind==TokenKind.LITERAL_LONG) { - push(Literal.getLongLiteral(t.data, toPos(t), 10)); - } else if (t.kind==TokenKind.LITERAL_HEXINT) { - push(Literal.getIntLiteral(t.data, toPos(t), 16)); - } else if (t.kind==TokenKind.LITERAL_HEXLONG) { - push(Literal.getLongLiteral(t.data, toPos(t), 16)); - } else if (t.kind==TokenKind.LITERAL_REAL) { - push(Literal.getRealLiteral(t.data, toPos(t),false)); - } else if (t.kind==TokenKind.LITERAL_REAL_FLOAT) { - push(Literal.getRealLiteral(t.data, toPos(t), true)); - } else if (peekIdentifierToken("true")) { - push(new BooleanLiteral(t.data,toPos(t),true)); - } else if (peekIdentifierToken("false")) { - push(new BooleanLiteral(t.data,toPos(t),false)); - } else if (t.kind==TokenKind.LITERAL_STRING) { - push(new StringLiteral(t.data,toPos(t),t.data)); - } else { - return false; - } - nextToken(); - return true; - } - - //parenExpr : LPAREN! expression RPAREN!; - private boolean maybeEatParenExpression() { - if (peekToken(TokenKind.LPAREN)) { - nextToken(); - SpelNodeImpl expr = eatExpression(); - eatToken(TokenKind.RPAREN); - push(expr); - return true; - } else { - return false; - } - } - - // relationalOperator - // : EQUAL | NOT_EQUAL | LESS_THAN | LESS_THAN_OR_EQUAL | GREATER_THAN - // | GREATER_THAN_OR_EQUAL | INSTANCEOF | BETWEEN | MATCHES - private Token maybeEatRelationalOperator() { - Token t = peekToken(); - if (t==null) { - return null; - } - if (t.isNumericRelationalOperator()) { - return t; - } - if (t.isIdentifier()) { - String idString = t.stringValue(); - if (idString.equalsIgnoreCase("instanceof")) { - return t.asInstanceOfToken(); - } else if (idString.equalsIgnoreCase("matches")) { - return t.asMatchesToken(); - } else if (idString.equalsIgnoreCase("between")) { - return t.asBetweenToken(); - } - } - return null; - } - - private Token eatToken(TokenKind expectedKind) { - Token t = nextToken(); - if (t==null) { - raiseInternalException( expressionString.length(), SpelMessage.OOD); - } - if (t.kind!=expectedKind) { - raiseInternalException(t.startpos,SpelMessage.NOT_EXPECTED_TOKEN, expectedKind.toString().toLowerCase(),t.getKind().toString().toLowerCase()); - } - return t; - } - - private boolean peekToken(TokenKind desiredTokenKind) { - return peekToken(desiredTokenKind,false); - } - - private boolean peekToken(TokenKind desiredTokenKind, boolean consumeIfMatched) { - if (!moreTokens()) { - return false; - } - Token t = peekToken(); - if (t.kind==desiredTokenKind) { - if (consumeIfMatched) { - tokenStreamPointer++; - } - return true; - } else { - if (desiredTokenKind == TokenKind.IDENTIFIER) { - // might be one of the textual forms of the operators (e.g. NE for != ) - in which case we can treat it as an identifier - // The list is represented here: Tokenizer.alternativeOperatorNames and those ones are in order in the TokenKind enum - if (t.kind.ordinal()>=TokenKind.DIV.ordinal() && t.kind.ordinal()<=TokenKind.NOT.ordinal() && t.data!=null) { - // if t.data were null, we'd know it wasn't the textual form, it was the symbol form - return true; - } - } - return false; - } - } - - private boolean peekToken(TokenKind possible1,TokenKind possible2) { - if (!moreTokens()) return false; - Token t = peekToken(); - return t.kind==possible1 || t.kind==possible2; - } - - private boolean peekToken(TokenKind possible1,TokenKind possible2, TokenKind possible3) { - if (!moreTokens()) return false; - Token t = peekToken(); - return t.kind==possible1 || t.kind==possible2 || t.kind==possible3; - } - - private boolean peekIdentifierToken(String identifierString) { - if (!moreTokens()) { - return false; - } - Token t = peekToken(); - return t.kind==TokenKind.IDENTIFIER && t.stringValue().equalsIgnoreCase(identifierString); - } - - private boolean peekSelectToken() { - if (!moreTokens()) return false; - Token t = peekToken(); - return t.kind==TokenKind.SELECT || t.kind==TokenKind.SELECT_FIRST || t.kind==TokenKind.SELECT_LAST; - } - - - private boolean moreTokens() { - return tokenStreamPointer<tokenStream.size(); - } - - private Token nextToken() { - if (tokenStreamPointer>=tokenStreamLength) { - return null; - } - return tokenStream.get(tokenStreamPointer++); - } - - private Token peekToken() { - if (tokenStreamPointer>=tokenStreamLength) { - return null; - } - return tokenStream.get(tokenStreamPointer); - } - - private void raiseInternalException(int pos, SpelMessage message,Object... inserts) { - throw new InternalParseException(new SpelParseException(expressionString,pos,message,inserts)); - } - - public String toString(Token t) { - if (t.getKind().hasPayload()) { - return t.stringValue(); - } else { - return t.kind.toString().toLowerCase(); - } - } - - private void checkRightOperand(Token token, SpelNodeImpl operandExpression) { - if (operandExpression==null) { - raiseInternalException(token.startpos,SpelMessage.RIGHT_OPERAND_PROBLEM); - } - } - - /** - * Compress the start and end of a token into a single int - */ - private int toPos(Token t) { - return (t.startpos<<16)+t.endpos; - } - - private int toPos(int start,int end) { - return (start<<16)+end; - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.expression.spel.standard; + +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; + +import org.springframework.expression.ParseException; +import org.springframework.expression.ParserContext; +import org.springframework.expression.common.TemplateAwareExpressionParser; +import org.springframework.expression.spel.InternalParseException; +import org.springframework.expression.spel.SpelMessage; +import org.springframework.expression.spel.SpelParseException; +import org.springframework.expression.spel.SpelParserConfiguration; +import org.springframework.expression.spel.ast.Assign; +import org.springframework.expression.spel.ast.BeanReference; +import org.springframework.expression.spel.ast.BooleanLiteral; +import org.springframework.expression.spel.ast.CompoundExpression; +import org.springframework.expression.spel.ast.ConstructorReference; +import org.springframework.expression.spel.ast.Elvis; +import org.springframework.expression.spel.ast.FunctionReference; +import org.springframework.expression.spel.ast.Identifier; +import org.springframework.expression.spel.ast.Indexer; +import org.springframework.expression.spel.ast.InlineList; +import org.springframework.expression.spel.ast.Literal; +import org.springframework.expression.spel.ast.MethodReference; +import org.springframework.expression.spel.ast.NullLiteral; +import org.springframework.expression.spel.ast.OpAnd; +import org.springframework.expression.spel.ast.OpDivide; +import org.springframework.expression.spel.ast.OpEQ; +import org.springframework.expression.spel.ast.OpGE; +import org.springframework.expression.spel.ast.OpGT; +import org.springframework.expression.spel.ast.OpLE; +import org.springframework.expression.spel.ast.OpLT; +import org.springframework.expression.spel.ast.OpMinus; +import org.springframework.expression.spel.ast.OpModulus; +import org.springframework.expression.spel.ast.OpMultiply; +import org.springframework.expression.spel.ast.OpNE; +import org.springframework.expression.spel.ast.OpOr; +import org.springframework.expression.spel.ast.OpPlus; +import org.springframework.expression.spel.ast.OperatorInstanceof; +import org.springframework.expression.spel.ast.OperatorMatches; +import org.springframework.expression.spel.ast.OperatorNot; +import org.springframework.expression.spel.ast.OperatorPower; +import org.springframework.expression.spel.ast.Projection; +import org.springframework.expression.spel.ast.PropertyOrFieldReference; +import org.springframework.expression.spel.ast.QualifiedIdentifier; +import org.springframework.expression.spel.ast.Selection; +import org.springframework.expression.spel.ast.SpelNodeImpl; +import org.springframework.expression.spel.ast.StringLiteral; +import org.springframework.expression.spel.ast.Ternary; +import org.springframework.expression.spel.ast.TypeReference; +import org.springframework.expression.spel.ast.VariableReference; +import org.springframework.util.Assert; + +/** + * Hand written SpEL parser. Instances are reusable but are not thread safe. + * + * @author Andy Clement + * @since 3.0 + */ +class InternalSpelExpressionParser extends TemplateAwareExpressionParser { + + // The expression being parsed + private String expressionString; + + // The token stream constructed from that expression string + private List<Token> tokenStream; + + // length of a populated token stream + private int tokenStreamLength; + + // Current location in the token stream when processing tokens + private int tokenStreamPointer; + + // For rules that build nodes, they are stacked here for return + private Stack<SpelNodeImpl> constructedNodes = new Stack<SpelNodeImpl>(); + + private SpelParserConfiguration configuration; + + + /** + * Create a parser with some configured behavior. + * @param configuration custom configuration options + */ + public InternalSpelExpressionParser(SpelParserConfiguration configuration) { + this.configuration = configuration; + } + + + @Override + protected SpelExpression doParseExpression(String expressionString, ParserContext context) throws ParseException { + try { + this.expressionString = expressionString; + Tokenizer tokenizer = new Tokenizer(expressionString); + tokenizer.process(); + tokenStream = tokenizer.getTokens(); + tokenStreamLength = tokenStream.size(); + tokenStreamPointer = 0; + constructedNodes.clear(); + SpelNodeImpl ast = eatExpression(); + if (moreTokens()) { + throw new SpelParseException(peekToken().startpos,SpelMessage.MORE_INPUT,toString(nextToken())); + } + Assert.isTrue(constructedNodes.isEmpty()); + return new SpelExpression(expressionString, ast, configuration); + } + catch (InternalParseException ipe) { + throw ipe.getCause(); + } + } + + // expression + // : logicalOrExpression + // ( (ASSIGN^ logicalOrExpression) + // | (DEFAULT^ logicalOrExpression) + // | (QMARK^ expression COLON! expression) + // | (ELVIS^ expression))?; + private SpelNodeImpl eatExpression() { + SpelNodeImpl expr = eatLogicalOrExpression(); + if (moreTokens()) { + Token t = peekToken(); + if (t.kind==TokenKind.ASSIGN) { // a=b + if (expr==null) { + expr = new NullLiteral(toPos(t.startpos-1,t.endpos-1)); + } + nextToken(); + SpelNodeImpl assignedValue = eatLogicalOrExpression(); + return new Assign(toPos(t),expr,assignedValue); + } else if (t.kind==TokenKind.ELVIS) { // a?:b (a if it isn't null, otherwise b) + if (expr==null) { + expr = new NullLiteral(toPos(t.startpos-1,t.endpos-2)); + } + nextToken(); // elvis has left the building + SpelNodeImpl valueIfNull = eatExpression(); + if (valueIfNull==null) { + valueIfNull = new NullLiteral(toPos(t.startpos+1,t.endpos+1)); + } + return new Elvis(toPos(t),expr,valueIfNull); + } else if (t.kind==TokenKind.QMARK) { // a?b:c + if (expr==null) { + expr = new NullLiteral(toPos(t.startpos-1,t.endpos-1)); + } + nextToken(); + SpelNodeImpl ifTrueExprValue = eatExpression(); + eatToken(TokenKind.COLON); + SpelNodeImpl ifFalseExprValue = eatExpression(); + return new Ternary(toPos(t),expr,ifTrueExprValue,ifFalseExprValue); + } + } + return expr; + } + + //logicalOrExpression : logicalAndExpression (OR^ logicalAndExpression)*; + private SpelNodeImpl eatLogicalOrExpression() { + SpelNodeImpl expr = eatLogicalAndExpression(); + while (peekIdentifierToken("or")) { + Token t = nextToken(); //consume OR + SpelNodeImpl rhExpr = eatLogicalAndExpression(); + checkRightOperand(t,rhExpr); + expr = new OpOr(toPos(t),expr,rhExpr); + } + return expr; + } + + // logicalAndExpression : relationalExpression (AND^ relationalExpression)*; + private SpelNodeImpl eatLogicalAndExpression() { + SpelNodeImpl expr = eatRelationalExpression(); + while (peekIdentifierToken("and")) { + Token t = nextToken();// consume 'AND' + SpelNodeImpl rhExpr = eatRelationalExpression(); + checkRightOperand(t,rhExpr); + expr = new OpAnd(toPos(t),expr,rhExpr); + } + return expr; + } + + // relationalExpression : sumExpression (relationalOperator^ sumExpression)?; + private SpelNodeImpl eatRelationalExpression() { + SpelNodeImpl expr = eatSumExpression(); + Token relationalOperatorToken = maybeEatRelationalOperator(); + if (relationalOperatorToken != null) { + Token t = nextToken(); //consume relational operator token + SpelNodeImpl rhExpr = eatSumExpression(); + checkRightOperand(t,rhExpr); + TokenKind tk = relationalOperatorToken.kind; + if (relationalOperatorToken.isNumericRelationalOperator()) { + int pos = toPos(t); + if (tk==TokenKind.GT) { + return new OpGT(pos,expr,rhExpr); + } else if (tk==TokenKind.LT) { + return new OpLT(pos,expr,rhExpr); + } else if (tk==TokenKind.LE) { + return new OpLE(pos,expr,rhExpr); + } else if (tk==TokenKind.GE) { + return new OpGE(pos,expr,rhExpr); + } else if (tk == TokenKind.EQ) { + return new OpEQ(pos,expr,rhExpr); + } else { + Assert.isTrue(tk == TokenKind.NE); + return new OpNE(pos,expr,rhExpr); + } + } + if (tk==TokenKind.INSTANCEOF) { + return new OperatorInstanceof(toPos(t),expr,rhExpr); + } else if (tk==TokenKind.MATCHES) { + return new OperatorMatches(toPos(t),expr,rhExpr); + } else { + Assert.isTrue(tk==TokenKind.BETWEEN); + return new org.springframework.expression.spel.ast.OperatorBetween(toPos(t),expr,rhExpr); + } + } + return expr; + } + + //sumExpression: productExpression ( (PLUS^ | MINUS^) productExpression)*; + private SpelNodeImpl eatSumExpression() { + SpelNodeImpl expr = eatProductExpression(); + while (peekToken(TokenKind.PLUS,TokenKind.MINUS)) { + Token t = nextToken();//consume PLUS or MINUS + SpelNodeImpl rhExpr = eatProductExpression(); + checkRightOperand(t,rhExpr); + if (t.kind==TokenKind.PLUS) { + expr = new OpPlus(toPos(t),expr,rhExpr); + } else { + Assert.isTrue(t.kind==TokenKind.MINUS); + expr = new OpMinus(toPos(t),expr,rhExpr); + } + } + return expr; + } + + // productExpression: powerExpr ((STAR^ | DIV^| MOD^) powerExpr)* ; + private SpelNodeImpl eatProductExpression() { + SpelNodeImpl expr = eatPowerExpression(); + while (peekToken(TokenKind.STAR,TokenKind.DIV,TokenKind.MOD)) { + Token t = nextToken(); // consume STAR/DIV/MOD + SpelNodeImpl rhExpr = eatPowerExpression(); + checkRightOperand(t,rhExpr); + if (t.kind==TokenKind.STAR) { + expr = new OpMultiply(toPos(t),expr,rhExpr); + } else if (t.kind==TokenKind.DIV) { + expr = new OpDivide(toPos(t),expr,rhExpr); + } else { + Assert.isTrue(t.kind==TokenKind.MOD); + expr = new OpModulus(toPos(t),expr,rhExpr); + } + } + return expr; + } + + // powerExpr : unaryExpression (POWER^ unaryExpression)? ; + private SpelNodeImpl eatPowerExpression() { + SpelNodeImpl expr = eatUnaryExpression(); + if (peekToken(TokenKind.POWER)) { + Token t = nextToken();//consume POWER + SpelNodeImpl rhExpr = eatUnaryExpression(); + checkRightOperand(t,rhExpr); + return new OperatorPower(toPos(t),expr, rhExpr); + } + return expr; + } + + // unaryExpression: (PLUS^ | MINUS^ | BANG^) unaryExpression | primaryExpression ; + private SpelNodeImpl eatUnaryExpression() { + if (peekToken(TokenKind.PLUS,TokenKind.MINUS,TokenKind.NOT)) { + Token t = nextToken(); + SpelNodeImpl expr = eatUnaryExpression(); + if (t.kind==TokenKind.NOT) { + return new OperatorNot(toPos(t),expr); + } else if (t.kind==TokenKind.PLUS) { + return new OpPlus(toPos(t),expr); + } else { + Assert.isTrue(t.kind==TokenKind.MINUS); + return new OpMinus(toPos(t),expr); + } + } else { + return eatPrimaryExpression(); + } + } + + // primaryExpression : startNode (node)? -> ^(EXPRESSION startNode (node)?); + private SpelNodeImpl eatPrimaryExpression() { + List<SpelNodeImpl> nodes = new ArrayList<SpelNodeImpl>(); + SpelNodeImpl start = eatStartNode(); // always a start node + nodes.add(start); + while (maybeEatNode()) { + nodes.add(pop()); + } + if (nodes.size()==1) { + return nodes.get(0); + } else { + return new CompoundExpression(toPos(start.getStartPosition(),nodes.get(nodes.size()-1).getEndPosition()),nodes.toArray(new SpelNodeImpl[nodes.size()])); + } + } + + // node : ((DOT dottedNode) | (SAFE_NAVI dottedNode) | nonDottedNode)+; + private boolean maybeEatNode() { + SpelNodeImpl expr = null; + if (peekToken(TokenKind.DOT,TokenKind.SAFE_NAVI)) { + expr = eatDottedNode(); + } else { + expr = maybeEatNonDottedNode(); + } + if (expr==null) { + return false; + } else { + push(expr); + return true; + } + } + + // nonDottedNode: indexer; + private SpelNodeImpl maybeEatNonDottedNode() { + if (peekToken(TokenKind.LSQUARE)) { + if (maybeEatIndexer()) { + return pop(); + } + } + return null; + } + + //dottedNode + // : ((methodOrProperty + // | functionOrVar + // | projection + // | selection + // | firstSelection + // | lastSelection + // )) + // ; + private SpelNodeImpl eatDottedNode() { + Token t = nextToken();// it was a '.' or a '?.' + boolean nullSafeNavigation = t.kind==TokenKind.SAFE_NAVI; + if (maybeEatMethodOrProperty(nullSafeNavigation) || maybeEatFunctionOrVar() || maybeEatProjection(nullSafeNavigation) || maybeEatSelection(nullSafeNavigation)) { + return pop(); + } + if (peekToken()==null) { + // unexpectedly ran out of data + raiseInternalException(t.startpos,SpelMessage.OOD); + } else { + raiseInternalException(t.startpos,SpelMessage.UNEXPECTED_DATA_AFTER_DOT,toString(peekToken())); + } + return null; + } + + // functionOrVar + // : (POUND ID LPAREN) => function + // | var + // + // function : POUND id=ID methodArgs -> ^(FUNCTIONREF[$id] methodArgs); + // var : POUND id=ID -> ^(VARIABLEREF[$id]); + private boolean maybeEatFunctionOrVar() { + if (!peekToken(TokenKind.HASH)) { + return false; + } + Token t = nextToken(); + Token functionOrVariableName = eatToken(TokenKind.IDENTIFIER); + SpelNodeImpl[] args = maybeEatMethodArgs(); + if (args==null) { + push(new VariableReference(functionOrVariableName.data,toPos(t.startpos,functionOrVariableName.endpos))); + return true; + } else { + push(new FunctionReference(functionOrVariableName.data,toPos(t.startpos,functionOrVariableName.endpos),args)); + return true; + } + } + + // methodArgs : LPAREN! (argument (COMMA! argument)* (COMMA!)?)? RPAREN!; + private SpelNodeImpl[] maybeEatMethodArgs() { + if (!peekToken(TokenKind.LPAREN)) { + return null; + } + List<SpelNodeImpl> args = new ArrayList<SpelNodeImpl>(); + consumeArguments(args); + eatToken(TokenKind.RPAREN); + return args.toArray(new SpelNodeImpl[args.size()]); + } + + private void eatConstructorArgs(List<SpelNodeImpl> accumulatedArguments) { + if (!peekToken(TokenKind.LPAREN)) { + throw new InternalParseException(new SpelParseException(expressionString,positionOf(peekToken()),SpelMessage.MISSING_CONSTRUCTOR_ARGS)); + } + consumeArguments(accumulatedArguments); + eatToken(TokenKind.RPAREN); + } + + /** + * Used for consuming arguments for either a method or a constructor call + */ + private void consumeArguments(List<SpelNodeImpl> accumulatedArguments) { + int pos = peekToken().startpos; + Token next = null; + do { + nextToken();// consume ( (first time through) or comma (subsequent times) + Token t = peekToken(); + if (t==null) { + raiseInternalException(pos,SpelMessage.RUN_OUT_OF_ARGUMENTS); + } + if (t.kind!=TokenKind.RPAREN) { + accumulatedArguments.add(eatExpression()); + } + next = peekToken(); + } while (next!=null && next.kind==TokenKind.COMMA); + if (next==null) { + raiseInternalException(pos,SpelMessage.RUN_OUT_OF_ARGUMENTS); + } + } + + private int positionOf(Token t) { + if (t==null) { + // if null assume the problem is because the right token was + // not found at the end of the expression + return expressionString.length(); + } else { + return t.startpos; + } + } + + + //startNode + // : parenExpr | literal + // | type + // | methodOrProperty + // | functionOrVar + // | projection + // | selection + // | firstSelection + // | lastSelection + // | indexer + // | constructor + private SpelNodeImpl eatStartNode() { + if (maybeEatLiteral()) { + return pop(); + } else if (maybeEatParenExpression()) { + return pop(); + } else if (maybeEatTypeReference() || maybeEatNullReference() || maybeEatConstructorReference() || maybeEatMethodOrProperty(false) || maybeEatFunctionOrVar()) { + return pop(); + } else if (maybeEatBeanReference()) { + return pop(); + } else if (maybeEatProjection(false) || maybeEatSelection(false) || maybeEatIndexer()) { + return pop(); + } else if (maybeEatInlineList()) { + return pop(); + } else { + return null; + } + } + + // parse: @beanname @'bean.name' + // quoted if dotted + private boolean maybeEatBeanReference() { + if (peekToken(TokenKind.BEAN_REF)) { + Token beanRefToken = nextToken(); + Token beanNameToken = null; + String beanname = null; + if (peekToken(TokenKind.IDENTIFIER)) { + beanNameToken = eatToken(TokenKind.IDENTIFIER); + beanname = beanNameToken.data; + } else if (peekToken(TokenKind.LITERAL_STRING)) { + beanNameToken = eatToken(TokenKind.LITERAL_STRING); + beanname = beanNameToken.stringValue(); + beanname = beanname.substring(1, beanname.length() - 1); + } else { + raiseInternalException(beanRefToken.startpos,SpelMessage.INVALID_BEAN_REFERENCE); + } + + BeanReference beanReference = new BeanReference(toPos(beanNameToken),beanname); + constructedNodes.push(beanReference); + return true; + } + return false; + } + + private boolean maybeEatTypeReference() { + if (peekToken(TokenKind.IDENTIFIER)) { + Token typeName = peekToken(); + if (!typeName.stringValue().equals("T")) { + return false; + } + nextToken(); + eatToken(TokenKind.LPAREN); + SpelNodeImpl node = eatPossiblyQualifiedId(); + // dotted qualified id + eatToken(TokenKind.RPAREN); + constructedNodes.push(new TypeReference(toPos(typeName),node)); + return true; + } + return false; + } + + private boolean maybeEatNullReference() { + if (peekToken(TokenKind.IDENTIFIER)) { + Token nullToken = peekToken(); + if (!nullToken.stringValue().equals("null")) { + return false; + } + nextToken(); + constructedNodes.push(new NullLiteral(toPos(nullToken))); + return true; + } + return false; + } + + //projection: PROJECT^ expression RCURLY!; + private boolean maybeEatProjection(boolean nullSafeNavigation) { + Token t = peekToken(); + if (!peekToken(TokenKind.PROJECT,true)) { + return false; + } + SpelNodeImpl expr = eatExpression(); + eatToken(TokenKind.RSQUARE); + constructedNodes.push(new Projection(nullSafeNavigation, toPos(t), expr)); + return true; + } + + // list = LCURLY (element (COMMA element)*) RCURLY + private boolean maybeEatInlineList() { + Token t = peekToken(); + if (!peekToken(TokenKind.LCURLY,true)) { + return false; + } + SpelNodeImpl expr = null; + Token closingCurly = peekToken(); + if (peekToken(TokenKind.RCURLY,true)) { + // empty list '[]' + expr = new InlineList(toPos(t.startpos,closingCurly.endpos)); + } else { + List<SpelNodeImpl> listElements = new ArrayList<SpelNodeImpl>(); + do { + listElements.add(eatExpression()); + } while (peekToken(TokenKind.COMMA,true)); + closingCurly = eatToken(TokenKind.RCURLY); + expr = new InlineList(toPos(t.startpos,closingCurly.endpos),listElements.toArray(new SpelNodeImpl[listElements.size()])); + } + constructedNodes.push(expr); + return true; + } + + private boolean maybeEatIndexer() { + Token t = peekToken(); + if (!peekToken(TokenKind.LSQUARE,true)) { + return false; + } + SpelNodeImpl expr = eatExpression(); + eatToken(TokenKind.RSQUARE); + constructedNodes.push(new Indexer(toPos(t),expr)); + return true; + } + + private boolean maybeEatSelection(boolean nullSafeNavigation) { + Token t = peekToken(); + if (!peekSelectToken()) { + return false; + } + nextToken(); + SpelNodeImpl expr = eatExpression(); + eatToken(TokenKind.RSQUARE); + if (t.kind==TokenKind.SELECT_FIRST) { + constructedNodes.push(new Selection(nullSafeNavigation,Selection.FIRST,toPos(t),expr)); + } else if (t.kind==TokenKind.SELECT_LAST) { + constructedNodes.push(new Selection(nullSafeNavigation,Selection.LAST,toPos(t),expr)); + } else { + constructedNodes.push(new Selection(nullSafeNavigation,Selection.ALL,toPos(t),expr)); + } + return true; + } + + /** + * Eat an identifier, possibly qualified (meaning that it is dotted). + * TODO AndyC Could create complete identifiers (a.b.c) here rather than a sequence of them? (a, b, c) + */ + private SpelNodeImpl eatPossiblyQualifiedId() { + List<SpelNodeImpl> qualifiedIdPieces = new ArrayList<SpelNodeImpl>(); + Token startnode = eatToken(TokenKind.IDENTIFIER); + qualifiedIdPieces.add(new Identifier(startnode.stringValue(),toPos(startnode))); + while (peekToken(TokenKind.DOT,true)) { + Token node = eatToken(TokenKind.IDENTIFIER); + qualifiedIdPieces.add(new Identifier(node.stringValue(),toPos(node))); + } + return new QualifiedIdentifier(toPos(startnode.startpos,qualifiedIdPieces.get(qualifiedIdPieces.size()-1).getEndPosition()),qualifiedIdPieces.toArray(new SpelNodeImpl[qualifiedIdPieces.size()])); + } + + // This is complicated due to the support for dollars in identifiers. Dollars are normally separate tokens but + // there we want to combine a series of identifiers and dollars into a single identifier + private boolean maybeEatMethodOrProperty(boolean nullSafeNavigation) { + if (peekToken(TokenKind.IDENTIFIER)) { + Token methodOrPropertyName = nextToken(); + SpelNodeImpl[] args = maybeEatMethodArgs(); + if (args==null) { + // property + push(new PropertyOrFieldReference(nullSafeNavigation, methodOrPropertyName.data,toPos(methodOrPropertyName))); + return true; + } else { + // methodreference + push(new MethodReference(nullSafeNavigation, methodOrPropertyName.data,toPos(methodOrPropertyName),args)); + // TODO what is the end position for a method reference? the name or the last arg? + return true; + } + } + return false; + + } + + //constructor + //: ('new' qualifiedId LPAREN) => 'new' qualifiedId ctorArgs -> ^(CONSTRUCTOR qualifiedId ctorArgs) + private boolean maybeEatConstructorReference() { + if (peekIdentifierToken("new")) { + Token newToken = nextToken(); + SpelNodeImpl possiblyQualifiedConstructorName = eatPossiblyQualifiedId(); + List<SpelNodeImpl> nodes = new ArrayList<SpelNodeImpl>(); + nodes.add(possiblyQualifiedConstructorName); + if (peekToken(TokenKind.LSQUARE)) { + // array initializer + List<SpelNodeImpl> dimensions = new ArrayList<SpelNodeImpl>(); + while (peekToken(TokenKind.LSQUARE,true)) { + if (!peekToken(TokenKind.RSQUARE)) { + dimensions.add(eatExpression()); + } else { + dimensions.add(null); + } + eatToken(TokenKind.RSQUARE); + } + if (maybeEatInlineList()) { + nodes.add(pop()); + } + push(new ConstructorReference(toPos(newToken), dimensions.toArray(new SpelNodeImpl[dimensions.size()]), + nodes.toArray(new SpelNodeImpl[nodes.size()]))); + } else { + // regular constructor invocation + eatConstructorArgs(nodes); + // TODO correct end position? + push(new ConstructorReference(toPos(newToken), nodes.toArray(new SpelNodeImpl[nodes.size()]))); + } + return true; + } + return false; + } + + private void push(SpelNodeImpl newNode) { + constructedNodes.push(newNode); + } + + private SpelNodeImpl pop() { + return constructedNodes.pop(); + } + + // literal + // : INTEGER_LITERAL + // | boolLiteral + // | STRING_LITERAL + // | HEXADECIMAL_INTEGER_LITERAL + // | REAL_LITERAL + // | DQ_STRING_LITERAL + // | NULL_LITERAL + private boolean maybeEatLiteral() { + Token t = peekToken(); + if (t==null) { + return false; + } + if (t.kind==TokenKind.LITERAL_INT) { + push(Literal.getIntLiteral(t.data, toPos(t), 10)); + } else if (t.kind==TokenKind.LITERAL_LONG) { + push(Literal.getLongLiteral(t.data, toPos(t), 10)); + } else if (t.kind==TokenKind.LITERAL_HEXINT) { + push(Literal.getIntLiteral(t.data, toPos(t), 16)); + } else if (t.kind==TokenKind.LITERAL_HEXLONG) { + push(Literal.getLongLiteral(t.data, toPos(t), 16)); + } else if (t.kind==TokenKind.LITERAL_REAL) { + push(Literal.getRealLiteral(t.data, toPos(t),false)); + } else if (t.kind==TokenKind.LITERAL_REAL_FLOAT) { + push(Literal.getRealLiteral(t.data, toPos(t), true)); + } else if (peekIdentifierToken("true")) { + push(new BooleanLiteral(t.data,toPos(t),true)); + } else if (peekIdentifierToken("false")) { + push(new BooleanLiteral(t.data,toPos(t),false)); + } else if (t.kind==TokenKind.LITERAL_STRING) { + push(new StringLiteral(t.data,toPos(t),t.data)); + } else { + return false; + } + nextToken(); + return true; + } + + //parenExpr : LPAREN! expression RPAREN!; + private boolean maybeEatParenExpression() { + if (peekToken(TokenKind.LPAREN)) { + nextToken(); + SpelNodeImpl expr = eatExpression(); + eatToken(TokenKind.RPAREN); + push(expr); + return true; + } else { + return false; + } + } + + // relationalOperator + // : EQUAL | NOT_EQUAL | LESS_THAN | LESS_THAN_OR_EQUAL | GREATER_THAN + // | GREATER_THAN_OR_EQUAL | INSTANCEOF | BETWEEN | MATCHES + private Token maybeEatRelationalOperator() { + Token t = peekToken(); + if (t==null) { + return null; + } + if (t.isNumericRelationalOperator()) { + return t; + } + if (t.isIdentifier()) { + String idString = t.stringValue(); + if (idString.equalsIgnoreCase("instanceof")) { + return t.asInstanceOfToken(); + } else if (idString.equalsIgnoreCase("matches")) { + return t.asMatchesToken(); + } else if (idString.equalsIgnoreCase("between")) { + return t.asBetweenToken(); + } + } + return null; + } + + private Token eatToken(TokenKind expectedKind) { + Token t = nextToken(); + if (t==null) { + raiseInternalException( expressionString.length(), SpelMessage.OOD); + } + if (t.kind!=expectedKind) { + raiseInternalException(t.startpos,SpelMessage.NOT_EXPECTED_TOKEN, expectedKind.toString().toLowerCase(),t.getKind().toString().toLowerCase()); + } + return t; + } + + private boolean peekToken(TokenKind desiredTokenKind) { + return peekToken(desiredTokenKind,false); + } + + private boolean peekToken(TokenKind desiredTokenKind, boolean consumeIfMatched) { + if (!moreTokens()) { + return false; + } + Token t = peekToken(); + if (t.kind==desiredTokenKind) { + if (consumeIfMatched) { + tokenStreamPointer++; + } + return true; + } else { + if (desiredTokenKind == TokenKind.IDENTIFIER) { + // might be one of the textual forms of the operators (e.g. NE for != ) - in which case we can treat it as an identifier + // The list is represented here: Tokenizer.alternativeOperatorNames and those ones are in order in the TokenKind enum + if (t.kind.ordinal()>=TokenKind.DIV.ordinal() && t.kind.ordinal()<=TokenKind.NOT.ordinal() && t.data!=null) { + // if t.data were null, we'd know it wasn't the textual form, it was the symbol form + return true; + } + } + return false; + } + } + + private boolean peekToken(TokenKind possible1,TokenKind possible2) { + if (!moreTokens()) return false; + Token t = peekToken(); + return t.kind==possible1 || t.kind==possible2; + } + + private boolean peekToken(TokenKind possible1,TokenKind possible2, TokenKind possible3) { + if (!moreTokens()) return false; + Token t = peekToken(); + return t.kind==possible1 || t.kind==possible2 || t.kind==possible3; + } + + private boolean peekIdentifierToken(String identifierString) { + if (!moreTokens()) { + return false; + } + Token t = peekToken(); + return t.kind==TokenKind.IDENTIFIER && t.stringValue().equalsIgnoreCase(identifierString); + } + + private boolean peekSelectToken() { + if (!moreTokens()) return false; + Token t = peekToken(); + return t.kind==TokenKind.SELECT || t.kind==TokenKind.SELECT_FIRST || t.kind==TokenKind.SELECT_LAST; + } + + + private boolean moreTokens() { + return tokenStreamPointer<tokenStream.size(); + } + + private Token nextToken() { + if (tokenStreamPointer>=tokenStreamLength) { + return null; + } + return tokenStream.get(tokenStreamPointer++); + } + + private Token peekToken() { + if (tokenStreamPointer>=tokenStreamLength) { + return null; + } + return tokenStream.get(tokenStreamPointer); + } + + private void raiseInternalException(int pos, SpelMessage message,Object... inserts) { + throw new InternalParseException(new SpelParseException(expressionString,pos,message,inserts)); + } + + public String toString(Token t) { + if (t.getKind().hasPayload()) { + return t.stringValue(); + } else { + return t.kind.toString().toLowerCase(); + } + } + + private void checkRightOperand(Token token, SpelNodeImpl operandExpression) { + if (operandExpression==null) { + raiseInternalException(token.startpos,SpelMessage.RIGHT_OPERAND_PROBLEM); + } + } + + /** + * Compress the start and end of a token into a single int + */ + private int toPos(Token t) { + return (t.startpos<<16)+t.endpos; + } + + private int toPos(int start,int end) { + return (start<<16)+end; + } + +} diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/spel/standard/SpelExpressionParser.java b/org.springframework.expression/src/main/java/org/springframework/expression/spel/standard/SpelExpressionParser.java index 1ec39ebaaf4..7c6c6f987ea 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/spel/standard/SpelExpressionParser.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/spel/standard/SpelExpressionParser.java @@ -1,63 +1,63 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.expression.spel.standard; - -import org.springframework.expression.ParseException; -import org.springframework.expression.ParserContext; -import org.springframework.expression.common.TemplateAwareExpressionParser; -import org.springframework.expression.spel.SpelParserConfiguration; -import org.springframework.util.Assert; - -/** - * SpEL parser. Instances are reusable and thread-safe. - * - * @author Andy Clement - * @author Juergen Hoeller - * @since 3.0 - */ -public class SpelExpressionParser extends TemplateAwareExpressionParser { - - private final SpelParserConfiguration configuration; - - - /** - * Create a parser with standard configuration. - */ - public SpelExpressionParser() { - this.configuration = new SpelParserConfiguration(false, false); - } - - /** - * Create a parser with some configured behavior. - * @param configuration custom configuration options - */ - public SpelExpressionParser(SpelParserConfiguration configuration) { - Assert.notNull(configuration, "SpelParserConfiguration must not be null"); - this.configuration = configuration; - } - - - @Override - protected SpelExpression doParseExpression(String expressionString, ParserContext context) throws ParseException { - return new InternalSpelExpressionParser(this.configuration).doParseExpression(expressionString, context); - } - - public SpelExpression parseRaw(String expressionString) throws ParseException { - return doParseExpression(expressionString, null); - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.expression.spel.standard; + +import org.springframework.expression.ParseException; +import org.springframework.expression.ParserContext; +import org.springframework.expression.common.TemplateAwareExpressionParser; +import org.springframework.expression.spel.SpelParserConfiguration; +import org.springframework.util.Assert; + +/** + * SpEL parser. Instances are reusable and thread-safe. + * + * @author Andy Clement + * @author Juergen Hoeller + * @since 3.0 + */ +public class SpelExpressionParser extends TemplateAwareExpressionParser { + + private final SpelParserConfiguration configuration; + + + /** + * Create a parser with standard configuration. + */ + public SpelExpressionParser() { + this.configuration = new SpelParserConfiguration(false, false); + } + + /** + * Create a parser with some configured behavior. + * @param configuration custom configuration options + */ + public SpelExpressionParser(SpelParserConfiguration configuration) { + Assert.notNull(configuration, "SpelParserConfiguration must not be null"); + this.configuration = configuration; + } + + + @Override + protected SpelExpression doParseExpression(String expressionString, ParserContext context) throws ParseException { + return new InternalSpelExpressionParser(this.configuration).doParseExpression(expressionString, context); + } + + public SpelExpression parseRaw(String expressionString) throws ParseException { + return doParseExpression(expressionString, null); + } + +} diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/spel/standard/Token.java b/org.springframework.expression/src/main/java/org/springframework/expression/spel/standard/Token.java index 1700cd6b92a..5d3d248fa0f 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/spel/standard/Token.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/spel/standard/Token.java @@ -1,87 +1,87 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.expression.spel.standard; - -/** - * Holder for a kind of token, the associated data and its position in the input data stream (start/end). - * - * @author Andy Clement - * @since 3.0 - */ -class Token { - - TokenKind kind; - String data; - int startpos; // index of first character - int endpos; // index of char after the last character - - /** - * Constructor for use when there is no particular data for the token (eg. TRUE or '+') - * @param startpos the exact start - * @param endpos the index to the last character - */ - Token(TokenKind tokenKind, int startpos, int endpos) { - this.kind = tokenKind; - this.startpos = startpos; - this.endpos = endpos; - } - - Token(TokenKind tokenKind, char[] tokenData, int pos, int endpos) { - this(tokenKind,pos,endpos); - this.data = new String(tokenData); - } - - - public TokenKind getKind() { - return kind; - } - - public String toString() { - StringBuilder s = new StringBuilder(); - s.append("[").append(kind.toString()); - if (kind.hasPayload()) { - s.append(":").append(data); - } - s.append("]"); - s.append("(").append(startpos).append(",").append(endpos).append(")"); - return s.toString(); - } - - public boolean isIdentifier() { - return kind==TokenKind.IDENTIFIER; - } - - public boolean isNumericRelationalOperator() { - return kind==TokenKind.GT || kind==TokenKind.GE || kind==TokenKind.LT || kind==TokenKind.LE || kind==TokenKind.EQ || kind==TokenKind.NE; - } - - public String stringValue() { - return data; - } - - public Token asInstanceOfToken() { - return new Token(TokenKind.INSTANCEOF,startpos,endpos); - } - - public Token asMatchesToken() { - return new Token(TokenKind.MATCHES,startpos,endpos); - } - - public Token asBetweenToken() { - return new Token(TokenKind.BETWEEN,startpos,endpos); - } +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.expression.spel.standard; + +/** + * Holder for a kind of token, the associated data and its position in the input data stream (start/end). + * + * @author Andy Clement + * @since 3.0 + */ +class Token { + + TokenKind kind; + String data; + int startpos; // index of first character + int endpos; // index of char after the last character + + /** + * Constructor for use when there is no particular data for the token (eg. TRUE or '+') + * @param startpos the exact start + * @param endpos the index to the last character + */ + Token(TokenKind tokenKind, int startpos, int endpos) { + this.kind = tokenKind; + this.startpos = startpos; + this.endpos = endpos; + } + + Token(TokenKind tokenKind, char[] tokenData, int pos, int endpos) { + this(tokenKind,pos,endpos); + this.data = new String(tokenData); + } + + + public TokenKind getKind() { + return kind; + } + + public String toString() { + StringBuilder s = new StringBuilder(); + s.append("[").append(kind.toString()); + if (kind.hasPayload()) { + s.append(":").append(data); + } + s.append("]"); + s.append("(").append(startpos).append(",").append(endpos).append(")"); + return s.toString(); + } + + public boolean isIdentifier() { + return kind==TokenKind.IDENTIFIER; + } + + public boolean isNumericRelationalOperator() { + return kind==TokenKind.GT || kind==TokenKind.GE || kind==TokenKind.LT || kind==TokenKind.LE || kind==TokenKind.EQ || kind==TokenKind.NE; + } + + public String stringValue() { + return data; + } + + public Token asInstanceOfToken() { + return new Token(TokenKind.INSTANCEOF,startpos,endpos); + } + + public Token asMatchesToken() { + return new Token(TokenKind.MATCHES,startpos,endpos); + } + + public Token asBetweenToken() { + return new Token(TokenKind.BETWEEN,startpos,endpos); + } } \ No newline at end of file diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/spel/standard/TokenKind.java b/org.springframework.expression/src/main/java/org/springframework/expression/spel/standard/TokenKind.java index c697396175b..78be627e7cb 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/spel/standard/TokenKind.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/spel/standard/TokenKind.java @@ -1,58 +1,58 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.expression.spel.standard; - -/** - * @author Andy Clement - * @since 3.0 - */ -enum TokenKind { - // ordered by priority - operands first - LITERAL_INT, LITERAL_LONG, LITERAL_HEXINT, LITERAL_HEXLONG, LITERAL_STRING, LITERAL_REAL, LITERAL_REAL_FLOAT, - LPAREN("("), RPAREN(")"), COMMA(","), IDENTIFIER, - COLON(":"),HASH("#"),RSQUARE("]"), LSQUARE("["), - LCURLY("{"),RCURLY("}"), - DOT("."), PLUS("+"), STAR("*"), MINUS("-"), SELECT_FIRST("^["), SELECT_LAST("$["), QMARK("?"), PROJECT("!["), - DIV("/"), GE(">="), GT(">"), LE("<="), LT("<"), EQ("=="), NE("!="), - MOD("%"), NOT("!"), ASSIGN("="), INSTANCEOF("instanceof"), MATCHES("matches"), BETWEEN("between"), - SELECT("?["), POWER("^"), - ELVIS("?:"), SAFE_NAVI("?."), BEAN_REF("@") - ; - - char[] tokenChars; - private boolean hasPayload; // is there more to this token than simply the kind - - private TokenKind(String tokenString) { - tokenChars = tokenString.toCharArray(); - hasPayload = tokenChars.length==0; - } - - private TokenKind() { - this(""); - } - - public String toString() { - return this.name()+(tokenChars.length!=0?"("+new String(tokenChars)+")":""); - } - - public boolean hasPayload() { - return hasPayload; - } - - public int getLength() { - return tokenChars.length; - } +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.expression.spel.standard; + +/** + * @author Andy Clement + * @since 3.0 + */ +enum TokenKind { + // ordered by priority - operands first + LITERAL_INT, LITERAL_LONG, LITERAL_HEXINT, LITERAL_HEXLONG, LITERAL_STRING, LITERAL_REAL, LITERAL_REAL_FLOAT, + LPAREN("("), RPAREN(")"), COMMA(","), IDENTIFIER, + COLON(":"),HASH("#"),RSQUARE("]"), LSQUARE("["), + LCURLY("{"),RCURLY("}"), + DOT("."), PLUS("+"), STAR("*"), MINUS("-"), SELECT_FIRST("^["), SELECT_LAST("$["), QMARK("?"), PROJECT("!["), + DIV("/"), GE(">="), GT(">"), LE("<="), LT("<"), EQ("=="), NE("!="), + MOD("%"), NOT("!"), ASSIGN("="), INSTANCEOF("instanceof"), MATCHES("matches"), BETWEEN("between"), + SELECT("?["), POWER("^"), + ELVIS("?:"), SAFE_NAVI("?."), BEAN_REF("@") + ; + + char[] tokenChars; + private boolean hasPayload; // is there more to this token than simply the kind + + private TokenKind(String tokenString) { + tokenChars = tokenString.toCharArray(); + hasPayload = tokenChars.length==0; + } + + private TokenKind() { + this(""); + } + + public String toString() { + return this.name()+(tokenChars.length!=0?"("+new String(tokenChars)+")":""); + } + + public boolean hasPayload() { + return hasPayload; + } + + public int getLength() { + return tokenChars.length; + } } \ No newline at end of file diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/spel/standard/Tokenizer.java b/org.springframework.expression/src/main/java/org/springframework/expression/spel/standard/Tokenizer.java index 3811fde747b..b2e01f90e8c 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/spel/standard/Tokenizer.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/spel/standard/Tokenizer.java @@ -1,507 +1,507 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.expression.spel.standard; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.springframework.expression.spel.InternalParseException; -import org.springframework.expression.spel.SpelMessage; -import org.springframework.expression.spel.SpelParseException; -import org.springframework.util.Assert; - -/** - * Lex some input data into a stream of tokens that can then be parsed. - * - * @author Andy Clement - * @since 3.0 - */ -class Tokenizer { - - String expressionString; - char[] toProcess; - int pos; - int max; - List<Token> tokens = new ArrayList<Token>(); - - public Tokenizer(String inputdata) { - this.expressionString = inputdata; - this.toProcess = (inputdata+"\0").toCharArray(); - this.max = toProcess.length; - this.pos = 0; - process(); - } - - public void process() { - while (pos<max) { - char ch = toProcess[pos]; - if (isAlphabetic(ch)) { - lexIdentifier(); - } else { - switch (ch) { - case '+': - pushCharToken(TokenKind.PLUS); - break; - case '_': // the other way to start an identifier - lexIdentifier(); - break; - case '-': - pushCharToken(TokenKind.MINUS); - break; - case ':': - pushCharToken(TokenKind.COLON); - break; - case '.': - pushCharToken(TokenKind.DOT); - break; - case ',': - pushCharToken(TokenKind.COMMA); - break; - case '*': - pushCharToken(TokenKind.STAR); - break; - case '/': - pushCharToken(TokenKind.DIV); - break; - case '%': - pushCharToken(TokenKind.MOD); - break; - case '(': - pushCharToken(TokenKind.LPAREN); - break; - case ')': - pushCharToken(TokenKind.RPAREN); - break; - case '[': - pushCharToken(TokenKind.LSQUARE); - break; - case '#': - pushCharToken(TokenKind.HASH); - break; - case ']': - pushCharToken(TokenKind.RSQUARE); - break; - case '{': - pushCharToken(TokenKind.LCURLY); - break; - case '}': - pushCharToken(TokenKind.RCURLY); - break; - case '@': - pushCharToken(TokenKind.BEAN_REF); - break; - case '^': - if (isTwoCharToken(TokenKind.SELECT_FIRST)) { - pushPairToken(TokenKind.SELECT_FIRST); - } else { - pushCharToken(TokenKind.POWER); - } - break; - case '!': - if (isTwoCharToken(TokenKind.NE)) { - pushPairToken(TokenKind.NE); - } else if (isTwoCharToken(TokenKind.PROJECT)) { - pushPairToken(TokenKind.PROJECT); - } else { - pushCharToken(TokenKind.NOT); - } - break; - case '=': - if (isTwoCharToken(TokenKind.EQ)) { - pushPairToken(TokenKind.EQ); - } else { - pushCharToken(TokenKind.ASSIGN); - } - break; - case '?': - if (isTwoCharToken(TokenKind.SELECT)) { - pushPairToken(TokenKind.SELECT); - } else if (isTwoCharToken(TokenKind.ELVIS)) { - pushPairToken(TokenKind.ELVIS); - } else if (isTwoCharToken(TokenKind.SAFE_NAVI)) { - pushPairToken(TokenKind.SAFE_NAVI); - } else { - pushCharToken(TokenKind.QMARK); - } - break; - case '$': - if (isTwoCharToken(TokenKind.SELECT_LAST)) { - pushPairToken(TokenKind.SELECT_LAST); - } else { - lexIdentifier(); - } - break; - case '>': - if (isTwoCharToken(TokenKind.GE)) { - pushPairToken(TokenKind.GE); - } else { - pushCharToken(TokenKind.GT); - } - break; - case '<': - if (isTwoCharToken(TokenKind.LE)) { - pushPairToken(TokenKind.LE); - } else { - pushCharToken(TokenKind.LT); - } - break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - lexNumericLiteral(ch=='0'); - break; - case ' ': - case '\t': - case '\r': - case '\n': - // drift over white space - pos++; - break; - case '\'': - lexQuotedStringLiteral(); - break; - case '"': - lexDoubleQuotedStringLiteral(); - break; - case 0: - // hit sentinel at end of value - pos++; // will take us to the end - break; - default: - throw new IllegalStateException("Cannot handle ("+Integer.valueOf(ch)+") '"+ch+"'"); - } - } - } - } - - public List<Token> getTokens() { - return tokens; - } - - - // STRING_LITERAL: '\''! (APOS|~'\'')* '\''!; - private void lexQuotedStringLiteral() { - int start = pos; - boolean terminated = false; - while (!terminated) { - pos++; - char ch = toProcess[pos]; - if (ch=='\'') { - // may not be the end if the char after is also a ' - if (toProcess[pos+1]=='\'') { - pos++; // skip over that too, and continue - } else { - terminated = true; - } - } - if (ch==0) { - throw new InternalParseException(new SpelParseException(expressionString,start,SpelMessage.NON_TERMINATING_QUOTED_STRING)); - } - } - pos++; - tokens.add(new Token(TokenKind.LITERAL_STRING, subarray(start,pos), start, pos)); - } - - // DQ_STRING_LITERAL: '"'! (~'"')* '"'!; - private void lexDoubleQuotedStringLiteral() { - int start = pos; - boolean terminated = false; - while (!terminated) { - pos++; - char ch = toProcess[pos]; - if (ch=='"') { - terminated = true; - } - if (ch==0) { - throw new InternalParseException(new SpelParseException(expressionString,start,SpelMessage.NON_TERMINATING_DOUBLE_QUOTED_STRING)); - } - } - pos++; - tokens.add(new Token(TokenKind.LITERAL_STRING, subarray(start,pos), start, pos)); - } - - -// REAL_LITERAL : -// ('.' (DECIMAL_DIGIT)+ (EXPONENT_PART)? (REAL_TYPE_SUFFIX)?) | -// ((DECIMAL_DIGIT)+ '.' (DECIMAL_DIGIT)+ (EXPONENT_PART)? (REAL_TYPE_SUFFIX)?) | -// ((DECIMAL_DIGIT)+ (EXPONENT_PART) (REAL_TYPE_SUFFIX)?) | -// ((DECIMAL_DIGIT)+ (REAL_TYPE_SUFFIX)); -// fragment INTEGER_TYPE_SUFFIX : ( 'L' | 'l' ); -// fragment HEX_DIGIT : '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9'|'A'|'B'|'C'|'D'|'E'|'F'|'a'|'b'|'c'|'d'|'e'|'f'; -// -// fragment EXPONENT_PART : 'e' (SIGN)* (DECIMAL_DIGIT)+ | 'E' (SIGN)* (DECIMAL_DIGIT)+ ; -// fragment SIGN : '+' | '-' ; -// fragment REAL_TYPE_SUFFIX : 'F' | 'f' | 'D' | 'd'; -// INTEGER_LITERAL -// : (DECIMAL_DIGIT)+ (INTEGER_TYPE_SUFFIX)?; - - private void lexNumericLiteral(boolean firstCharIsZero) { - boolean isReal = false; - int start = pos; - char ch = toProcess[pos+1]; - boolean isHex = ch=='x' || ch=='X'; - - // deal with hexadecimal - if (firstCharIsZero && isHex) { - pos=pos+1; - do { - pos++; - } while (isHexadecimalDigit(toProcess[pos])); - if (isChar('L','l')) { - pushHexIntToken(subarray(start+2,pos),true, start, pos); - pos++; - } else { - pushHexIntToken(subarray(start+2,pos),false, start, pos); - } - return; - } - - // real numbers must have leading digits - - // Consume first part of number - do { - pos++; - } while (isDigit(toProcess[pos])); - - // a '.' indicates this number is a real - ch = toProcess[pos]; - if (ch=='.') { - isReal = true; - // carry on consuming digits - do { - pos++; - } while (isDigit(toProcess[pos])); - } - - int endOfNumber = pos; - - // Now there may or may not be an exponent - - // is it a long ? - if (isChar('L','l')) { - if (isReal) { // 3.4L - not allowed - throw new InternalParseException(new SpelParseException(expressionString,start,SpelMessage.REAL_CANNOT_BE_LONG)); - } - pushIntToken(subarray(start, endOfNumber), true, start, endOfNumber); - pos++; - } else if (isExponentChar(toProcess[pos])) { - isReal = true; // if it wasnt before, it is now - pos++; - char possibleSign = toProcess[pos]; - if (isSign(possibleSign)) { - pos++; - } - - // exponent digits - do { - pos++; - } while (isDigit(toProcess[pos])); - boolean isFloat = false; - if (isFloatSuffix(toProcess[pos])) { - isFloat = true; - endOfNumber = ++pos; - } else if (isDoubleSuffix(toProcess[pos])) { - endOfNumber = ++pos; - } - pushRealToken(subarray(start,pos), isFloat, start, pos); - } else { - ch = toProcess[pos]; - boolean isFloat = false; - if (isFloatSuffix(ch)) { - isReal = true; - isFloat = true; - endOfNumber = ++pos; - } else if (isDoubleSuffix(ch)) { - isReal = true; - endOfNumber = ++pos; - } - if (isReal) { - pushRealToken(subarray(start,endOfNumber), isFloat, start, endOfNumber); - } else { - pushIntToken(subarray(start,endOfNumber), false, start, endOfNumber); - } - } - } - - // if this is changed, it must remain sorted - private static final String[] alternativeOperatorNames = { "DIV","EQ","GE","GT","LE","LT","MOD","NE","NOT"}; - - private void lexIdentifier() { - int start = pos; - do { - pos++; - } while (isIdentifier(toProcess[pos])); - char[] subarray = subarray(start,pos); - - // Check if this is the alternative (textual) representation of an operator (see alternativeOperatorNames) - if ((pos-start)==2 || (pos-start)==3) { - String asString = new String(subarray).toUpperCase(); - int idx = Arrays.binarySearch(alternativeOperatorNames,asString); - if (idx>=0) { - pushOneCharOrTwoCharToken(TokenKind.valueOf(asString),start,subarray); - return; - } - } - tokens.add(new Token(TokenKind.IDENTIFIER,subarray,start,pos)); - } - - private void pushIntToken(char[] data,boolean isLong, int start, int end) { - if (isLong) { - tokens.add(new Token(TokenKind.LITERAL_LONG,data, start, end)); - } else { - tokens.add(new Token(TokenKind.LITERAL_INT,data, start, end)); - } - } - - private void pushHexIntToken(char[] data,boolean isLong, int start, int end) { - if (data.length==0) { - if (isLong) { - throw new InternalParseException(new SpelParseException(expressionString,start,SpelMessage.NOT_A_LONG,expressionString.substring(start,end+1))); - } else { - throw new InternalParseException(new SpelParseException(expressionString,start,SpelMessage.NOT_AN_INTEGER,expressionString.substring(start,end))); - } - } - if (isLong) { - tokens.add(new Token(TokenKind.LITERAL_HEXLONG, data, start, end)); - } else { - tokens.add(new Token(TokenKind.LITERAL_HEXINT, data, start, end)); - } - } - - private void pushRealToken(char[] data, boolean isFloat, int start, int end) { - if (isFloat) { - tokens.add(new Token(TokenKind.LITERAL_REAL_FLOAT, data, start, end)); - } else { - tokens.add(new Token(TokenKind.LITERAL_REAL, data, start, end)); - } - } - - private char[] subarray(int start, int end) { - char[] result = new char[end - start]; - System.arraycopy(toProcess, start, result, 0, end - start); - return result; - } - - /** - * Check if this might be a two character token. - */ - private boolean isTwoCharToken(TokenKind kind) { - Assert.isTrue(kind.tokenChars.length == 2); - Assert.isTrue(toProcess[pos] == kind.tokenChars[0]); - return toProcess[pos+1] == kind.tokenChars[1]; - } - - /** - * Push a token of just one character in length. - */ - private void pushCharToken(TokenKind kind) { - tokens.add(new Token(kind,pos,pos+1)); - pos++; - } - - /** - * Push a token of two characters in length. - */ - private void pushPairToken(TokenKind kind) { - tokens.add(new Token(kind,pos,pos+2)); - pos+=2; - } - - private void pushOneCharOrTwoCharToken(TokenKind kind, int pos, char[] data) { - tokens.add(new Token(kind,data,pos,pos+kind.getLength())); - } - - // ID: ('a'..'z'|'A'..'Z'|'_'|'$') ('a'..'z'|'A'..'Z'|'_'|'$'|'0'..'9'|DOT_ESCAPED)*; - private boolean isIdentifier(char ch) { - return isAlphabetic(ch) || isDigit(ch) || ch=='_' || ch=='$'; - } - - private boolean isChar(char a,char b) { - char ch = toProcess[pos]; - return ch==a || ch==b; - } - - private boolean isExponentChar(char ch) { - return ch=='e' || ch=='E'; - } - - private boolean isFloatSuffix(char ch) { - return ch=='f' || ch=='F'; - } - - private boolean isDoubleSuffix(char ch) { - return ch=='d' || ch=='D'; - } - - private boolean isSign(char ch) { - return ch=='+' || ch=='-'; - } - - private boolean isDigit(char ch) { - if (ch>255) { - return false; - } - return (flags[ch] & IS_DIGIT)!=0; - } - - private boolean isAlphabetic(char ch) { - if (ch>255) { - return false; - } - return (flags[ch] & IS_ALPHA)!=0; - } - - private boolean isHexadecimalDigit(char ch) { - if (ch>255) { - return false; - } - return (flags[ch] & IS_HEXDIGIT)!=0; - } - - private static final byte flags[] = new byte[256]; - private static final byte IS_DIGIT=0x01; - private static final byte IS_HEXDIGIT=0x02; - private static final byte IS_ALPHA=0x04; - - static { - for (int ch='0';ch<='9';ch++) { - flags[ch]|=IS_DIGIT | IS_HEXDIGIT; - } - for (int ch='A';ch<='F';ch++) { - flags[ch]|= IS_HEXDIGIT; - } - for (int ch='a';ch<='f';ch++) { - flags[ch]|= IS_HEXDIGIT; - } - for (int ch='A';ch<='Z';ch++) { - flags[ch]|= IS_ALPHA; - } - for (int ch='a';ch<='z';ch++) { - flags[ch]|= IS_ALPHA; - } - } - - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.expression.spel.standard; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.springframework.expression.spel.InternalParseException; +import org.springframework.expression.spel.SpelMessage; +import org.springframework.expression.spel.SpelParseException; +import org.springframework.util.Assert; + +/** + * Lex some input data into a stream of tokens that can then be parsed. + * + * @author Andy Clement + * @since 3.0 + */ +class Tokenizer { + + String expressionString; + char[] toProcess; + int pos; + int max; + List<Token> tokens = new ArrayList<Token>(); + + public Tokenizer(String inputdata) { + this.expressionString = inputdata; + this.toProcess = (inputdata+"\0").toCharArray(); + this.max = toProcess.length; + this.pos = 0; + process(); + } + + public void process() { + while (pos<max) { + char ch = toProcess[pos]; + if (isAlphabetic(ch)) { + lexIdentifier(); + } else { + switch (ch) { + case '+': + pushCharToken(TokenKind.PLUS); + break; + case '_': // the other way to start an identifier + lexIdentifier(); + break; + case '-': + pushCharToken(TokenKind.MINUS); + break; + case ':': + pushCharToken(TokenKind.COLON); + break; + case '.': + pushCharToken(TokenKind.DOT); + break; + case ',': + pushCharToken(TokenKind.COMMA); + break; + case '*': + pushCharToken(TokenKind.STAR); + break; + case '/': + pushCharToken(TokenKind.DIV); + break; + case '%': + pushCharToken(TokenKind.MOD); + break; + case '(': + pushCharToken(TokenKind.LPAREN); + break; + case ')': + pushCharToken(TokenKind.RPAREN); + break; + case '[': + pushCharToken(TokenKind.LSQUARE); + break; + case '#': + pushCharToken(TokenKind.HASH); + break; + case ']': + pushCharToken(TokenKind.RSQUARE); + break; + case '{': + pushCharToken(TokenKind.LCURLY); + break; + case '}': + pushCharToken(TokenKind.RCURLY); + break; + case '@': + pushCharToken(TokenKind.BEAN_REF); + break; + case '^': + if (isTwoCharToken(TokenKind.SELECT_FIRST)) { + pushPairToken(TokenKind.SELECT_FIRST); + } else { + pushCharToken(TokenKind.POWER); + } + break; + case '!': + if (isTwoCharToken(TokenKind.NE)) { + pushPairToken(TokenKind.NE); + } else if (isTwoCharToken(TokenKind.PROJECT)) { + pushPairToken(TokenKind.PROJECT); + } else { + pushCharToken(TokenKind.NOT); + } + break; + case '=': + if (isTwoCharToken(TokenKind.EQ)) { + pushPairToken(TokenKind.EQ); + } else { + pushCharToken(TokenKind.ASSIGN); + } + break; + case '?': + if (isTwoCharToken(TokenKind.SELECT)) { + pushPairToken(TokenKind.SELECT); + } else if (isTwoCharToken(TokenKind.ELVIS)) { + pushPairToken(TokenKind.ELVIS); + } else if (isTwoCharToken(TokenKind.SAFE_NAVI)) { + pushPairToken(TokenKind.SAFE_NAVI); + } else { + pushCharToken(TokenKind.QMARK); + } + break; + case '$': + if (isTwoCharToken(TokenKind.SELECT_LAST)) { + pushPairToken(TokenKind.SELECT_LAST); + } else { + lexIdentifier(); + } + break; + case '>': + if (isTwoCharToken(TokenKind.GE)) { + pushPairToken(TokenKind.GE); + } else { + pushCharToken(TokenKind.GT); + } + break; + case '<': + if (isTwoCharToken(TokenKind.LE)) { + pushPairToken(TokenKind.LE); + } else { + pushCharToken(TokenKind.LT); + } + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + lexNumericLiteral(ch=='0'); + break; + case ' ': + case '\t': + case '\r': + case '\n': + // drift over white space + pos++; + break; + case '\'': + lexQuotedStringLiteral(); + break; + case '"': + lexDoubleQuotedStringLiteral(); + break; + case 0: + // hit sentinel at end of value + pos++; // will take us to the end + break; + default: + throw new IllegalStateException("Cannot handle ("+Integer.valueOf(ch)+") '"+ch+"'"); + } + } + } + } + + public List<Token> getTokens() { + return tokens; + } + + + // STRING_LITERAL: '\''! (APOS|~'\'')* '\''!; + private void lexQuotedStringLiteral() { + int start = pos; + boolean terminated = false; + while (!terminated) { + pos++; + char ch = toProcess[pos]; + if (ch=='\'') { + // may not be the end if the char after is also a ' + if (toProcess[pos+1]=='\'') { + pos++; // skip over that too, and continue + } else { + terminated = true; + } + } + if (ch==0) { + throw new InternalParseException(new SpelParseException(expressionString,start,SpelMessage.NON_TERMINATING_QUOTED_STRING)); + } + } + pos++; + tokens.add(new Token(TokenKind.LITERAL_STRING, subarray(start,pos), start, pos)); + } + + // DQ_STRING_LITERAL: '"'! (~'"')* '"'!; + private void lexDoubleQuotedStringLiteral() { + int start = pos; + boolean terminated = false; + while (!terminated) { + pos++; + char ch = toProcess[pos]; + if (ch=='"') { + terminated = true; + } + if (ch==0) { + throw new InternalParseException(new SpelParseException(expressionString,start,SpelMessage.NON_TERMINATING_DOUBLE_QUOTED_STRING)); + } + } + pos++; + tokens.add(new Token(TokenKind.LITERAL_STRING, subarray(start,pos), start, pos)); + } + + +// REAL_LITERAL : +// ('.' (DECIMAL_DIGIT)+ (EXPONENT_PART)? (REAL_TYPE_SUFFIX)?) | +// ((DECIMAL_DIGIT)+ '.' (DECIMAL_DIGIT)+ (EXPONENT_PART)? (REAL_TYPE_SUFFIX)?) | +// ((DECIMAL_DIGIT)+ (EXPONENT_PART) (REAL_TYPE_SUFFIX)?) | +// ((DECIMAL_DIGIT)+ (REAL_TYPE_SUFFIX)); +// fragment INTEGER_TYPE_SUFFIX : ( 'L' | 'l' ); +// fragment HEX_DIGIT : '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9'|'A'|'B'|'C'|'D'|'E'|'F'|'a'|'b'|'c'|'d'|'e'|'f'; +// +// fragment EXPONENT_PART : 'e' (SIGN)* (DECIMAL_DIGIT)+ | 'E' (SIGN)* (DECIMAL_DIGIT)+ ; +// fragment SIGN : '+' | '-' ; +// fragment REAL_TYPE_SUFFIX : 'F' | 'f' | 'D' | 'd'; +// INTEGER_LITERAL +// : (DECIMAL_DIGIT)+ (INTEGER_TYPE_SUFFIX)?; + + private void lexNumericLiteral(boolean firstCharIsZero) { + boolean isReal = false; + int start = pos; + char ch = toProcess[pos+1]; + boolean isHex = ch=='x' || ch=='X'; + + // deal with hexadecimal + if (firstCharIsZero && isHex) { + pos=pos+1; + do { + pos++; + } while (isHexadecimalDigit(toProcess[pos])); + if (isChar('L','l')) { + pushHexIntToken(subarray(start+2,pos),true, start, pos); + pos++; + } else { + pushHexIntToken(subarray(start+2,pos),false, start, pos); + } + return; + } + + // real numbers must have leading digits + + // Consume first part of number + do { + pos++; + } while (isDigit(toProcess[pos])); + + // a '.' indicates this number is a real + ch = toProcess[pos]; + if (ch=='.') { + isReal = true; + // carry on consuming digits + do { + pos++; + } while (isDigit(toProcess[pos])); + } + + int endOfNumber = pos; + + // Now there may or may not be an exponent + + // is it a long ? + if (isChar('L','l')) { + if (isReal) { // 3.4L - not allowed + throw new InternalParseException(new SpelParseException(expressionString,start,SpelMessage.REAL_CANNOT_BE_LONG)); + } + pushIntToken(subarray(start, endOfNumber), true, start, endOfNumber); + pos++; + } else if (isExponentChar(toProcess[pos])) { + isReal = true; // if it wasnt before, it is now + pos++; + char possibleSign = toProcess[pos]; + if (isSign(possibleSign)) { + pos++; + } + + // exponent digits + do { + pos++; + } while (isDigit(toProcess[pos])); + boolean isFloat = false; + if (isFloatSuffix(toProcess[pos])) { + isFloat = true; + endOfNumber = ++pos; + } else if (isDoubleSuffix(toProcess[pos])) { + endOfNumber = ++pos; + } + pushRealToken(subarray(start,pos), isFloat, start, pos); + } else { + ch = toProcess[pos]; + boolean isFloat = false; + if (isFloatSuffix(ch)) { + isReal = true; + isFloat = true; + endOfNumber = ++pos; + } else if (isDoubleSuffix(ch)) { + isReal = true; + endOfNumber = ++pos; + } + if (isReal) { + pushRealToken(subarray(start,endOfNumber), isFloat, start, endOfNumber); + } else { + pushIntToken(subarray(start,endOfNumber), false, start, endOfNumber); + } + } + } + + // if this is changed, it must remain sorted + private static final String[] alternativeOperatorNames = { "DIV","EQ","GE","GT","LE","LT","MOD","NE","NOT"}; + + private void lexIdentifier() { + int start = pos; + do { + pos++; + } while (isIdentifier(toProcess[pos])); + char[] subarray = subarray(start,pos); + + // Check if this is the alternative (textual) representation of an operator (see alternativeOperatorNames) + if ((pos-start)==2 || (pos-start)==3) { + String asString = new String(subarray).toUpperCase(); + int idx = Arrays.binarySearch(alternativeOperatorNames,asString); + if (idx>=0) { + pushOneCharOrTwoCharToken(TokenKind.valueOf(asString),start,subarray); + return; + } + } + tokens.add(new Token(TokenKind.IDENTIFIER,subarray,start,pos)); + } + + private void pushIntToken(char[] data,boolean isLong, int start, int end) { + if (isLong) { + tokens.add(new Token(TokenKind.LITERAL_LONG,data, start, end)); + } else { + tokens.add(new Token(TokenKind.LITERAL_INT,data, start, end)); + } + } + + private void pushHexIntToken(char[] data,boolean isLong, int start, int end) { + if (data.length==0) { + if (isLong) { + throw new InternalParseException(new SpelParseException(expressionString,start,SpelMessage.NOT_A_LONG,expressionString.substring(start,end+1))); + } else { + throw new InternalParseException(new SpelParseException(expressionString,start,SpelMessage.NOT_AN_INTEGER,expressionString.substring(start,end))); + } + } + if (isLong) { + tokens.add(new Token(TokenKind.LITERAL_HEXLONG, data, start, end)); + } else { + tokens.add(new Token(TokenKind.LITERAL_HEXINT, data, start, end)); + } + } + + private void pushRealToken(char[] data, boolean isFloat, int start, int end) { + if (isFloat) { + tokens.add(new Token(TokenKind.LITERAL_REAL_FLOAT, data, start, end)); + } else { + tokens.add(new Token(TokenKind.LITERAL_REAL, data, start, end)); + } + } + + private char[] subarray(int start, int end) { + char[] result = new char[end - start]; + System.arraycopy(toProcess, start, result, 0, end - start); + return result; + } + + /** + * Check if this might be a two character token. + */ + private boolean isTwoCharToken(TokenKind kind) { + Assert.isTrue(kind.tokenChars.length == 2); + Assert.isTrue(toProcess[pos] == kind.tokenChars[0]); + return toProcess[pos+1] == kind.tokenChars[1]; + } + + /** + * Push a token of just one character in length. + */ + private void pushCharToken(TokenKind kind) { + tokens.add(new Token(kind,pos,pos+1)); + pos++; + } + + /** + * Push a token of two characters in length. + */ + private void pushPairToken(TokenKind kind) { + tokens.add(new Token(kind,pos,pos+2)); + pos+=2; + } + + private void pushOneCharOrTwoCharToken(TokenKind kind, int pos, char[] data) { + tokens.add(new Token(kind,data,pos,pos+kind.getLength())); + } + + // ID: ('a'..'z'|'A'..'Z'|'_'|'$') ('a'..'z'|'A'..'Z'|'_'|'$'|'0'..'9'|DOT_ESCAPED)*; + private boolean isIdentifier(char ch) { + return isAlphabetic(ch) || isDigit(ch) || ch=='_' || ch=='$'; + } + + private boolean isChar(char a,char b) { + char ch = toProcess[pos]; + return ch==a || ch==b; + } + + private boolean isExponentChar(char ch) { + return ch=='e' || ch=='E'; + } + + private boolean isFloatSuffix(char ch) { + return ch=='f' || ch=='F'; + } + + private boolean isDoubleSuffix(char ch) { + return ch=='d' || ch=='D'; + } + + private boolean isSign(char ch) { + return ch=='+' || ch=='-'; + } + + private boolean isDigit(char ch) { + if (ch>255) { + return false; + } + return (flags[ch] & IS_DIGIT)!=0; + } + + private boolean isAlphabetic(char ch) { + if (ch>255) { + return false; + } + return (flags[ch] & IS_ALPHA)!=0; + } + + private boolean isHexadecimalDigit(char ch) { + if (ch>255) { + return false; + } + return (flags[ch] & IS_HEXDIGIT)!=0; + } + + private static final byte flags[] = new byte[256]; + private static final byte IS_DIGIT=0x01; + private static final byte IS_HEXDIGIT=0x02; + private static final byte IS_ALPHA=0x04; + + static { + for (int ch='0';ch<='9';ch++) { + flags[ch]|=IS_DIGIT | IS_HEXDIGIT; + } + for (int ch='A';ch<='F';ch++) { + flags[ch]|= IS_HEXDIGIT; + } + for (int ch='a';ch<='f';ch++) { + flags[ch]|= IS_HEXDIGIT; + } + for (int ch='A';ch<='Z';ch++) { + flags[ch]|= IS_ALPHA; + } + for (int ch='a';ch<='z';ch++) { + flags[ch]|= IS_ALPHA; + } + } + + +} diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/BooleanTypedValue.java b/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/BooleanTypedValue.java index bf350081b5d..b397f1ac04c 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/BooleanTypedValue.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/BooleanTypedValue.java @@ -1,46 +1,46 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.expression.spel.support; - -import org.springframework.expression.TypedValue; - -/** - * @author Andy Clement - * @since 3.0 - */ -public class BooleanTypedValue extends TypedValue { - - public static final BooleanTypedValue TRUE = new BooleanTypedValue(true); - - public static final BooleanTypedValue FALSE = new BooleanTypedValue(false); - - - private BooleanTypedValue(boolean b) { - super(b); - } - - - public static BooleanTypedValue forValue(boolean b) { - if (b) { - return TRUE; - } - else { - return FALSE; - } - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.expression.spel.support; + +import org.springframework.expression.TypedValue; + +/** + * @author Andy Clement + * @since 3.0 + */ +public class BooleanTypedValue extends TypedValue { + + public static final BooleanTypedValue TRUE = new BooleanTypedValue(true); + + public static final BooleanTypedValue FALSE = new BooleanTypedValue(false); + + + private BooleanTypedValue(boolean b) { + super(b); + } + + + public static BooleanTypedValue forValue(boolean b) { + if (b) { + return TRUE; + } + else { + return FALSE; + } + } + +} diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectionHelper.java b/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectionHelper.java index 9a8a35c60ba..40dcbc2ca76 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectionHelper.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectionHelper.java @@ -1,507 +1,507 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.expression.spel.support; - -import java.lang.reflect.Array; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; - -import org.springframework.core.MethodParameter; -import org.springframework.core.convert.TypeDescriptor; -import org.springframework.expression.EvaluationException; -import org.springframework.expression.TypeConverter; -import org.springframework.expression.spel.SpelEvaluationException; -import org.springframework.expression.spel.SpelMessage; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; -import org.springframework.util.MethodInvoker; - -/** - * Utility methods used by the reflection resolver code to discover the appropriate - * methods/constructors and fields that should be used in expressions. - * - * @author Andy Clement - * @author Juergen Hoeller - * @since 3.0 - */ -public class ReflectionHelper { - - /** - * Compare argument arrays and return information about whether they match. A supplied type converter - * and conversionAllowed flag allow for matches to take into account that a type may be transformed - * into a different type by the converter. - * @param expectedArgTypes the array of types the method/constructor is expecting - * @param suppliedArgTypes the array of types that are being supplied at the point of invocation - * @param typeConverter a registered type converter - * @return a MatchInfo object indicating what kind of match it was or null if it was not a match - */ - static ArgumentsMatchInfo compareArguments( - List<TypeDescriptor> expectedArgTypes, List<TypeDescriptor> suppliedArgTypes, TypeConverter typeConverter) { - - Assert.isTrue(expectedArgTypes.size() == suppliedArgTypes.size(), - "Expected argument types and supplied argument types should be arrays of same length"); - - ArgsMatchKind match = ArgsMatchKind.EXACT; - List<Integer> argsRequiringConversion = null; - for (int i = 0; i < expectedArgTypes.size() && match != null; i++) { - TypeDescriptor suppliedArg = suppliedArgTypes.get(i); - TypeDescriptor expectedArg = expectedArgTypes.get(i); - if (!expectedArg.equals(suppliedArg)) { - // The user may supply null - and that will be ok unless a primitive is expected - if (suppliedArg == null) { - if (expectedArg.isPrimitive()) { - match = null; - } - } - else { - if (suppliedArg.isAssignableTo(expectedArg)) { - if (match != ArgsMatchKind.REQUIRES_CONVERSION) { - match = ArgsMatchKind.CLOSE; - } - } - else if (typeConverter.canConvert(suppliedArg, expectedArg)) { - if (argsRequiringConversion == null) { - argsRequiringConversion = new ArrayList<Integer>(); - } - argsRequiringConversion.add(i); - match = ArgsMatchKind.REQUIRES_CONVERSION; - } - else { - match = null; - } - } - } - } - if (match == null) { - return null; - } - else { - if (match == ArgsMatchKind.REQUIRES_CONVERSION) { - int[] argsArray = new int[argsRequiringConversion.size()]; - for (int i = 0; i < argsRequiringConversion.size(); i++) { - argsArray[i] = argsRequiringConversion.get(i); - } - return new ArgumentsMatchInfo(match, argsArray); - } - else { - return new ArgumentsMatchInfo(match); - } - } - } - - /** - * Based on {@link MethodInvoker#getTypeDifferenceWeight(Class[], Object[])} but operates on TypeDescriptors. - */ - public static int getTypeDifferenceWeight(List<TypeDescriptor> paramTypes, List<TypeDescriptor> argTypes) { - int result = 0; - for (int i = 0,max=paramTypes.size(); i < max; i++) { - TypeDescriptor argType = argTypes.get(i); - TypeDescriptor paramType = paramTypes.get(i); - if (argType == null) { - if (paramType.isPrimitive()) { - return Integer.MAX_VALUE; - } - } - if (!ClassUtils.isAssignable(paramType.getClass(), argType.getClass())) { - return Integer.MAX_VALUE; - } - if (argType != null) { - Class paramTypeClazz = paramType.getType(); - if (paramTypeClazz.isPrimitive()) { - paramTypeClazz = Object.class; - } - Class superClass = argType.getClass().getSuperclass(); - while (superClass != null) { - if (paramType.equals(superClass)) { - result = result + 2; - superClass = null; - } - else if (ClassUtils.isAssignable(paramTypeClazz, superClass)) { - result = result + 2; - superClass = superClass.getSuperclass(); - } - else { - superClass = null; - } - } - if (paramTypeClazz.isInterface()) { - result = result + 1; - } - } - } - return result; - } - - /** - * Compare argument arrays and return information about whether they match. A supplied type converter and - * conversionAllowed flag allow for matches to take into account that a type may be transformed into a different - * type by the converter. This variant of compareArguments also allows for a varargs match. - * @param expectedArgTypes the array of types the method/constructor is expecting - * @param suppliedArgTypes the array of types that are being supplied at the point of invocation - * @param typeConverter a registered type converter - * @return a MatchInfo object indicating what kind of match it was or null if it was not a match - */ - static ArgumentsMatchInfo compareArgumentsVarargs( - List<TypeDescriptor> expectedArgTypes, List<TypeDescriptor> suppliedArgTypes, TypeConverter typeConverter) { - - Assert.isTrue(expectedArgTypes != null && expectedArgTypes.size() > 0, - "Expected arguments must at least include one array (the vargargs parameter)"); - Assert.isTrue(expectedArgTypes.get(expectedArgTypes.size() - 1).isArray(), - "Final expected argument should be array type (the varargs parameter)"); - - ArgsMatchKind match = ArgsMatchKind.EXACT; - List<Integer> argsRequiringConversion = null; - - // Check up until the varargs argument: - - // Deal with the arguments up to 'expected number' - 1 (that is everything but the varargs argument) - int argCountUpToVarargs = expectedArgTypes.size() - 1; - for (int i = 0; i < argCountUpToVarargs && match != null; i++) { - TypeDescriptor suppliedArg = suppliedArgTypes.get(i); - TypeDescriptor expectedArg = expectedArgTypes.get(i); - if (suppliedArg == null) { - if (expectedArg.isPrimitive()) { - match = null; - } - } - else { - if (!expectedArg.equals(suppliedArg)) { - if (suppliedArg.isAssignableTo(expectedArg)) { - if (match != ArgsMatchKind.REQUIRES_CONVERSION) { - match = ArgsMatchKind.CLOSE; - } - } - else if (typeConverter.canConvert(suppliedArg, expectedArg)) { - if (argsRequiringConversion == null) { - argsRequiringConversion = new ArrayList<Integer>(); - } - argsRequiringConversion.add(i); - match = ArgsMatchKind.REQUIRES_CONVERSION; - } - else { - match = null; - } - } - } - } - // If already confirmed it cannot be a match, then return - if (match == null) { - return null; - } - - if (suppliedArgTypes.size() == expectedArgTypes.size() && - expectedArgTypes.get(expectedArgTypes.size() - 1).equals( - suppliedArgTypes.get(suppliedArgTypes.size() - 1))) { - // Special case: there is one parameter left and it is an array and it matches the varargs - // expected argument - that is a match, the caller has already built the array. Proceed with it. - } - else { - // Now... we have the final argument in the method we are checking as a match and we have 0 or more other - // arguments left to pass to it. - Class varargsParameterType = expectedArgTypes.get(expectedArgTypes.size() - 1).getElementTypeDescriptor().getType(); - - // All remaining parameters must be of this type or convertable to this type - for (int i = expectedArgTypes.size() - 1; i < suppliedArgTypes.size(); i++) { - TypeDescriptor suppliedArg = suppliedArgTypes.get(i); - if (suppliedArg == null) { - if (varargsParameterType.isPrimitive()) { - match = null; - } - } else { - if (varargsParameterType != suppliedArg.getType()) { - if (ClassUtils.isAssignable(varargsParameterType, suppliedArg.getType())) { - if (match != ArgsMatchKind.REQUIRES_CONVERSION) { - match = ArgsMatchKind.CLOSE; - } - } - else if (typeConverter.canConvert(suppliedArg, TypeDescriptor.valueOf(varargsParameterType))) { - if (argsRequiringConversion == null) { - argsRequiringConversion = new ArrayList<Integer>(); - } - argsRequiringConversion.add(i); - match = ArgsMatchKind.REQUIRES_CONVERSION; - } - else { - match = null; - } - } - } - } - } - - if (match == null) { - return null; - } - else { - if (match == ArgsMatchKind.REQUIRES_CONVERSION) { - int[] argsArray = new int[argsRequiringConversion.size()]; - for (int i = 0; i < argsRequiringConversion.size(); i++) { - argsArray[i] = argsRequiringConversion.get(i); - } - return new ArgumentsMatchInfo(match, argsArray); - } - else { - return new ArgumentsMatchInfo(match); - } - } - } - - /** - * Takes an input set of argument values and, following the positions specified in the int array, - * it converts them to the types specified as the required parameter types. The arguments are - * converted 'in-place' in the input array. - * @param converter the type converter to use for attempting conversions - * @param arguments the actual arguments that need conversion - * @param methodOrCtor the target Method or Constructor - * @param argumentsRequiringConversion details which of the input arguments for sure need conversion - * @param varargsPosition the known position of the varargs argument, if any - * @throws EvaluationException if a problem occurs during conversion - */ - static void convertArguments(TypeConverter converter, Object[] arguments, Object methodOrCtor, - int[] argumentsRequiringConversion, Integer varargsPosition) throws EvaluationException { - if (varargsPosition == null) { - for (int i = 0; i < arguments.length; i++) { - TypeDescriptor targetType = new TypeDescriptor(MethodParameter.forMethodOrConstructor(methodOrCtor, i)); - Object argument = arguments[i]; - arguments[i] = converter.convertValue(argument, TypeDescriptor.forObject(argument), targetType); - } - } else { - for (int i = 0; i < varargsPosition; i++) { - TypeDescriptor targetType = new TypeDescriptor(MethodParameter.forMethodOrConstructor(methodOrCtor, i)); - Object argument = arguments[i]; - arguments[i] = converter.convertValue(argument, TypeDescriptor.forObject(argument), targetType); - } - MethodParameter methodParam = MethodParameter.forMethodOrConstructor(methodOrCtor, varargsPosition); - if (varargsPosition == arguments.length - 1) { - TypeDescriptor targetType = new TypeDescriptor(methodParam); - Object argument = arguments[varargsPosition]; - arguments[varargsPosition] = converter.convertValue(argument, TypeDescriptor.forObject(argument), targetType); - } else { - TypeDescriptor targetType = TypeDescriptor.nested(methodParam, 1); - for (int i = varargsPosition; i < arguments.length; i++) { - Object argument = arguments[i]; - arguments[i] = converter.convertValue(argument, TypeDescriptor.forObject(argument), targetType); - } - } - } - } - - /** - * Convert a supplied set of arguments into the requested types. If the parameterTypes are related to - * a varargs method then the final entry in the parameterTypes array is going to be an array itself whose - * component type should be used as the conversion target for extraneous arguments. (For example, if the - * parameterTypes are {Integer, String[]} and the input arguments are {Integer, boolean, float} then both - * the boolean and float must be converted to strings). This method does not repackage the arguments - * into a form suitable for the varargs invocation - * @param converter the converter to use for type conversions - * @param arguments the arguments to convert to the requested parameter types - * @param method the target Method - * @throws SpelEvaluationException if there is a problem with conversion - */ - public static void convertAllArguments(TypeConverter converter, Object[] arguments, Method method) throws SpelEvaluationException { - Integer varargsPosition = null; - if (method.isVarArgs()) { - Class[] paramTypes = method.getParameterTypes(); - varargsPosition = paramTypes.length - 1; - } - for (int argPosition = 0; argPosition < arguments.length; argPosition++) { - TypeDescriptor targetType; - if (varargsPosition != null && argPosition >= varargsPosition) { - MethodParameter methodParam = new MethodParameter(method, varargsPosition); - targetType = TypeDescriptor.nested(methodParam, 1); - } - else { - targetType = new TypeDescriptor(new MethodParameter(method, argPosition)); - } - try { - Object argument = arguments[argPosition]; - if (argument != null && !targetType.getObjectType().isInstance(argument)) { - if (converter == null) { - throw new SpelEvaluationException(SpelMessage.TYPE_CONVERSION_ERROR, argument.getClass().getName(), targetType); - } - arguments[argPosition] = converter.convertValue(argument, TypeDescriptor.forObject(argument), targetType); - } - } - catch (EvaluationException ex) { - // allows for another type converter throwing a different kind of EvaluationException - if (ex instanceof SpelEvaluationException) { - throw (SpelEvaluationException)ex; - } - else { - throw new SpelEvaluationException(ex, SpelMessage.TYPE_CONVERSION_ERROR,arguments[argPosition].getClass().getName(), targetType); - } - } - } - } - - /** - * Package up the arguments so that they correctly match what is expected in parameterTypes. For example, if - * parameterTypes is (int, String[]) because the second parameter was declared String... then if arguments is - * [1,"a","b"] then it must be repackaged as [1,new String[]{"a","b"}] in order to match the expected - * parameterTypes. - * @param requiredParameterTypes the types of the parameters for the invocation - * @param args the arguments to be setup ready for the invocation - * @return a repackaged array of arguments where any varargs setup has been done - */ - public static Object[] setupArgumentsForVarargsInvocation(Class[] requiredParameterTypes, Object... args) { - // Check if array already built for final argument - int parameterCount = requiredParameterTypes.length; - int argumentCount = args.length; - - // Check if repackaging is needed: - if (parameterCount != args.length || - requiredParameterTypes[parameterCount - 1] != - (args[argumentCount - 1] == null ? null : args[argumentCount - 1].getClass())) { - int arraySize = 0; // zero size array if nothing to pass as the varargs parameter - if (argumentCount >= parameterCount) { - arraySize = argumentCount - (parameterCount - 1); - } - - // Create an array for the varargs arguments - Object[] newArgs = new Object[parameterCount]; - for (int i = 0; i < newArgs.length - 1; i++) { - newArgs[i] = args[i]; - } - // Now sort out the final argument, which is the varargs one. Before entering this - // method the arguments should have been converted to the box form of the required type. - Class<?> componentType = requiredParameterTypes[parameterCount-1].getComponentType(); - if (componentType.isPrimitive()) { - if (componentType==Integer.TYPE) { - int[] repackagedArguments = (int[]) Array.newInstance(componentType, arraySize); - for (int i = 0; i < arraySize; i++) { - repackagedArguments[i] = ((Integer)args[parameterCount + i - 1]).intValue(); - } - newArgs[newArgs.length - 1] = repackagedArguments; - } else if(componentType==Float.TYPE) { - float[] repackagedArguments = (float[]) Array.newInstance(componentType, arraySize); - for (int i = 0; i < arraySize; i++) { - repackagedArguments[i] = ((Float)args[parameterCount + i - 1]).floatValue(); - } - newArgs[newArgs.length - 1] = repackagedArguments; - } else if(componentType==Double.TYPE) { - double[] repackagedArguments = (double[]) Array.newInstance(componentType, arraySize); - for (int i = 0; i < arraySize; i++) { - repackagedArguments[i] = ((Double)args[parameterCount + i - 1]).doubleValue(); - } - newArgs[newArgs.length - 1] = repackagedArguments; - } else if(componentType==Short.TYPE) { - short[] repackagedArguments = (short[]) Array.newInstance(componentType, arraySize); - for (int i = 0; i < arraySize; i++) { - repackagedArguments[i] = ((Short)args[parameterCount + i - 1]).shortValue(); - } - newArgs[newArgs.length - 1] = repackagedArguments; - } else if(componentType==Character.TYPE) { - char[] repackagedArguments = (char[]) Array.newInstance(componentType, arraySize); - for (int i = 0; i < arraySize; i++) { - repackagedArguments[i] = ((Character)args[parameterCount + i - 1]).charValue(); - } - newArgs[newArgs.length - 1] = repackagedArguments; - } else if(componentType==Byte.TYPE) { - byte[] repackagedArguments = (byte[]) Array.newInstance(componentType, arraySize); - for (int i = 0; i < arraySize; i++) { - repackagedArguments[i] = ((Byte)args[parameterCount + i - 1]).byteValue(); - } - newArgs[newArgs.length - 1] = repackagedArguments; - } else if(componentType==Boolean.TYPE) { - boolean[] repackagedArguments = (boolean[]) Array.newInstance(componentType, arraySize); - for (int i = 0; i < arraySize; i++) { - repackagedArguments[i] = ((Boolean)args[parameterCount + i - 1]).booleanValue(); - } - newArgs[newArgs.length - 1] = repackagedArguments; - } else if(componentType==Long.TYPE) { - long[] repackagedArguments = (long[]) Array.newInstance(componentType, arraySize); - for (int i = 0; i < arraySize; i++) { - repackagedArguments[i] = ((Long)args[parameterCount + i - 1]).longValue(); - } - newArgs[newArgs.length - 1] = repackagedArguments; - } - } else { - Object[] repackagedArguments = (Object[]) Array.newInstance(componentType, arraySize); - // Copy all but the varargs arguments - for (int i = 0; i < arraySize; i++) { - repackagedArguments[i] = args[parameterCount + i - 1]; - } - newArgs[newArgs.length - 1] = repackagedArguments; - } - return newArgs; - } - return args; - } - - - public static enum ArgsMatchKind { - // An exact match is where the parameter types exactly match what the method/constructor being invoked is expecting - EXACT, - // A close match is where the parameter types either exactly match or are assignment compatible with the method/constructor being invoked - CLOSE, - // A conversion match is where the type converter must be used to transform some of the parameter types - REQUIRES_CONVERSION - } - - - /** - * An instance of ArgumentsMatchInfo describes what kind of match was achieved between two sets of arguments - the set that a - * method/constructor is expecting and the set that are being supplied at the point of invocation. If the kind - * indicates that conversion is required for some of the arguments then the arguments that require conversion are - * listed in the argsRequiringConversion array. - */ - public static class ArgumentsMatchInfo { - - public final ArgsMatchKind kind; - - public int[] argsRequiringConversion; - - ArgumentsMatchInfo(ArgsMatchKind kind, int[] integers) { - this.kind = kind; - this.argsRequiringConversion = integers; - } - - ArgumentsMatchInfo(ArgsMatchKind kind) { - this.kind = kind; - } - - public boolean isExactMatch() { - return (this.kind == ArgsMatchKind.EXACT); - } - - public boolean isCloseMatch() { - return (this.kind == ArgsMatchKind.CLOSE); - } - - public boolean isMatchRequiringConversion() { - return (this.kind == ArgsMatchKind.REQUIRES_CONVERSION); - } - - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("ArgumentMatch: ").append(this.kind); - if (this.argsRequiringConversion != null) { - sb.append(" (argsForConversion:"); - for (int i = 0; i < this.argsRequiringConversion.length;i++) { - if (i > 0) { - sb.append(","); - } - sb.append(this.argsRequiringConversion[i]); - } - sb.append(")"); - } - return sb.toString(); - } - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.expression.spel.support; + +import java.lang.reflect.Array; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + +import org.springframework.core.MethodParameter; +import org.springframework.core.convert.TypeDescriptor; +import org.springframework.expression.EvaluationException; +import org.springframework.expression.TypeConverter; +import org.springframework.expression.spel.SpelEvaluationException; +import org.springframework.expression.spel.SpelMessage; +import org.springframework.util.Assert; +import org.springframework.util.ClassUtils; +import org.springframework.util.MethodInvoker; + +/** + * Utility methods used by the reflection resolver code to discover the appropriate + * methods/constructors and fields that should be used in expressions. + * + * @author Andy Clement + * @author Juergen Hoeller + * @since 3.0 + */ +public class ReflectionHelper { + + /** + * Compare argument arrays and return information about whether they match. A supplied type converter + * and conversionAllowed flag allow for matches to take into account that a type may be transformed + * into a different type by the converter. + * @param expectedArgTypes the array of types the method/constructor is expecting + * @param suppliedArgTypes the array of types that are being supplied at the point of invocation + * @param typeConverter a registered type converter + * @return a MatchInfo object indicating what kind of match it was or null if it was not a match + */ + static ArgumentsMatchInfo compareArguments( + List<TypeDescriptor> expectedArgTypes, List<TypeDescriptor> suppliedArgTypes, TypeConverter typeConverter) { + + Assert.isTrue(expectedArgTypes.size() == suppliedArgTypes.size(), + "Expected argument types and supplied argument types should be arrays of same length"); + + ArgsMatchKind match = ArgsMatchKind.EXACT; + List<Integer> argsRequiringConversion = null; + for (int i = 0; i < expectedArgTypes.size() && match != null; i++) { + TypeDescriptor suppliedArg = suppliedArgTypes.get(i); + TypeDescriptor expectedArg = expectedArgTypes.get(i); + if (!expectedArg.equals(suppliedArg)) { + // The user may supply null - and that will be ok unless a primitive is expected + if (suppliedArg == null) { + if (expectedArg.isPrimitive()) { + match = null; + } + } + else { + if (suppliedArg.isAssignableTo(expectedArg)) { + if (match != ArgsMatchKind.REQUIRES_CONVERSION) { + match = ArgsMatchKind.CLOSE; + } + } + else if (typeConverter.canConvert(suppliedArg, expectedArg)) { + if (argsRequiringConversion == null) { + argsRequiringConversion = new ArrayList<Integer>(); + } + argsRequiringConversion.add(i); + match = ArgsMatchKind.REQUIRES_CONVERSION; + } + else { + match = null; + } + } + } + } + if (match == null) { + return null; + } + else { + if (match == ArgsMatchKind.REQUIRES_CONVERSION) { + int[] argsArray = new int[argsRequiringConversion.size()]; + for (int i = 0; i < argsRequiringConversion.size(); i++) { + argsArray[i] = argsRequiringConversion.get(i); + } + return new ArgumentsMatchInfo(match, argsArray); + } + else { + return new ArgumentsMatchInfo(match); + } + } + } + + /** + * Based on {@link MethodInvoker#getTypeDifferenceWeight(Class[], Object[])} but operates on TypeDescriptors. + */ + public static int getTypeDifferenceWeight(List<TypeDescriptor> paramTypes, List<TypeDescriptor> argTypes) { + int result = 0; + for (int i = 0,max=paramTypes.size(); i < max; i++) { + TypeDescriptor argType = argTypes.get(i); + TypeDescriptor paramType = paramTypes.get(i); + if (argType == null) { + if (paramType.isPrimitive()) { + return Integer.MAX_VALUE; + } + } + if (!ClassUtils.isAssignable(paramType.getClass(), argType.getClass())) { + return Integer.MAX_VALUE; + } + if (argType != null) { + Class paramTypeClazz = paramType.getType(); + if (paramTypeClazz.isPrimitive()) { + paramTypeClazz = Object.class; + } + Class superClass = argType.getClass().getSuperclass(); + while (superClass != null) { + if (paramType.equals(superClass)) { + result = result + 2; + superClass = null; + } + else if (ClassUtils.isAssignable(paramTypeClazz, superClass)) { + result = result + 2; + superClass = superClass.getSuperclass(); + } + else { + superClass = null; + } + } + if (paramTypeClazz.isInterface()) { + result = result + 1; + } + } + } + return result; + } + + /** + * Compare argument arrays and return information about whether they match. A supplied type converter and + * conversionAllowed flag allow for matches to take into account that a type may be transformed into a different + * type by the converter. This variant of compareArguments also allows for a varargs match. + * @param expectedArgTypes the array of types the method/constructor is expecting + * @param suppliedArgTypes the array of types that are being supplied at the point of invocation + * @param typeConverter a registered type converter + * @return a MatchInfo object indicating what kind of match it was or null if it was not a match + */ + static ArgumentsMatchInfo compareArgumentsVarargs( + List<TypeDescriptor> expectedArgTypes, List<TypeDescriptor> suppliedArgTypes, TypeConverter typeConverter) { + + Assert.isTrue(expectedArgTypes != null && expectedArgTypes.size() > 0, + "Expected arguments must at least include one array (the vargargs parameter)"); + Assert.isTrue(expectedArgTypes.get(expectedArgTypes.size() - 1).isArray(), + "Final expected argument should be array type (the varargs parameter)"); + + ArgsMatchKind match = ArgsMatchKind.EXACT; + List<Integer> argsRequiringConversion = null; + + // Check up until the varargs argument: + + // Deal with the arguments up to 'expected number' - 1 (that is everything but the varargs argument) + int argCountUpToVarargs = expectedArgTypes.size() - 1; + for (int i = 0; i < argCountUpToVarargs && match != null; i++) { + TypeDescriptor suppliedArg = suppliedArgTypes.get(i); + TypeDescriptor expectedArg = expectedArgTypes.get(i); + if (suppliedArg == null) { + if (expectedArg.isPrimitive()) { + match = null; + } + } + else { + if (!expectedArg.equals(suppliedArg)) { + if (suppliedArg.isAssignableTo(expectedArg)) { + if (match != ArgsMatchKind.REQUIRES_CONVERSION) { + match = ArgsMatchKind.CLOSE; + } + } + else if (typeConverter.canConvert(suppliedArg, expectedArg)) { + if (argsRequiringConversion == null) { + argsRequiringConversion = new ArrayList<Integer>(); + } + argsRequiringConversion.add(i); + match = ArgsMatchKind.REQUIRES_CONVERSION; + } + else { + match = null; + } + } + } + } + // If already confirmed it cannot be a match, then return + if (match == null) { + return null; + } + + if (suppliedArgTypes.size() == expectedArgTypes.size() && + expectedArgTypes.get(expectedArgTypes.size() - 1).equals( + suppliedArgTypes.get(suppliedArgTypes.size() - 1))) { + // Special case: there is one parameter left and it is an array and it matches the varargs + // expected argument - that is a match, the caller has already built the array. Proceed with it. + } + else { + // Now... we have the final argument in the method we are checking as a match and we have 0 or more other + // arguments left to pass to it. + Class varargsParameterType = expectedArgTypes.get(expectedArgTypes.size() - 1).getElementTypeDescriptor().getType(); + + // All remaining parameters must be of this type or convertable to this type + for (int i = expectedArgTypes.size() - 1; i < suppliedArgTypes.size(); i++) { + TypeDescriptor suppliedArg = suppliedArgTypes.get(i); + if (suppliedArg == null) { + if (varargsParameterType.isPrimitive()) { + match = null; + } + } else { + if (varargsParameterType != suppliedArg.getType()) { + if (ClassUtils.isAssignable(varargsParameterType, suppliedArg.getType())) { + if (match != ArgsMatchKind.REQUIRES_CONVERSION) { + match = ArgsMatchKind.CLOSE; + } + } + else if (typeConverter.canConvert(suppliedArg, TypeDescriptor.valueOf(varargsParameterType))) { + if (argsRequiringConversion == null) { + argsRequiringConversion = new ArrayList<Integer>(); + } + argsRequiringConversion.add(i); + match = ArgsMatchKind.REQUIRES_CONVERSION; + } + else { + match = null; + } + } + } + } + } + + if (match == null) { + return null; + } + else { + if (match == ArgsMatchKind.REQUIRES_CONVERSION) { + int[] argsArray = new int[argsRequiringConversion.size()]; + for (int i = 0; i < argsRequiringConversion.size(); i++) { + argsArray[i] = argsRequiringConversion.get(i); + } + return new ArgumentsMatchInfo(match, argsArray); + } + else { + return new ArgumentsMatchInfo(match); + } + } + } + + /** + * Takes an input set of argument values and, following the positions specified in the int array, + * it converts them to the types specified as the required parameter types. The arguments are + * converted 'in-place' in the input array. + * @param converter the type converter to use for attempting conversions + * @param arguments the actual arguments that need conversion + * @param methodOrCtor the target Method or Constructor + * @param argumentsRequiringConversion details which of the input arguments for sure need conversion + * @param varargsPosition the known position of the varargs argument, if any + * @throws EvaluationException if a problem occurs during conversion + */ + static void convertArguments(TypeConverter converter, Object[] arguments, Object methodOrCtor, + int[] argumentsRequiringConversion, Integer varargsPosition) throws EvaluationException { + if (varargsPosition == null) { + for (int i = 0; i < arguments.length; i++) { + TypeDescriptor targetType = new TypeDescriptor(MethodParameter.forMethodOrConstructor(methodOrCtor, i)); + Object argument = arguments[i]; + arguments[i] = converter.convertValue(argument, TypeDescriptor.forObject(argument), targetType); + } + } else { + for (int i = 0; i < varargsPosition; i++) { + TypeDescriptor targetType = new TypeDescriptor(MethodParameter.forMethodOrConstructor(methodOrCtor, i)); + Object argument = arguments[i]; + arguments[i] = converter.convertValue(argument, TypeDescriptor.forObject(argument), targetType); + } + MethodParameter methodParam = MethodParameter.forMethodOrConstructor(methodOrCtor, varargsPosition); + if (varargsPosition == arguments.length - 1) { + TypeDescriptor targetType = new TypeDescriptor(methodParam); + Object argument = arguments[varargsPosition]; + arguments[varargsPosition] = converter.convertValue(argument, TypeDescriptor.forObject(argument), targetType); + } else { + TypeDescriptor targetType = TypeDescriptor.nested(methodParam, 1); + for (int i = varargsPosition; i < arguments.length; i++) { + Object argument = arguments[i]; + arguments[i] = converter.convertValue(argument, TypeDescriptor.forObject(argument), targetType); + } + } + } + } + + /** + * Convert a supplied set of arguments into the requested types. If the parameterTypes are related to + * a varargs method then the final entry in the parameterTypes array is going to be an array itself whose + * component type should be used as the conversion target for extraneous arguments. (For example, if the + * parameterTypes are {Integer, String[]} and the input arguments are {Integer, boolean, float} then both + * the boolean and float must be converted to strings). This method does not repackage the arguments + * into a form suitable for the varargs invocation + * @param converter the converter to use for type conversions + * @param arguments the arguments to convert to the requested parameter types + * @param method the target Method + * @throws SpelEvaluationException if there is a problem with conversion + */ + public static void convertAllArguments(TypeConverter converter, Object[] arguments, Method method) throws SpelEvaluationException { + Integer varargsPosition = null; + if (method.isVarArgs()) { + Class[] paramTypes = method.getParameterTypes(); + varargsPosition = paramTypes.length - 1; + } + for (int argPosition = 0; argPosition < arguments.length; argPosition++) { + TypeDescriptor targetType; + if (varargsPosition != null && argPosition >= varargsPosition) { + MethodParameter methodParam = new MethodParameter(method, varargsPosition); + targetType = TypeDescriptor.nested(methodParam, 1); + } + else { + targetType = new TypeDescriptor(new MethodParameter(method, argPosition)); + } + try { + Object argument = arguments[argPosition]; + if (argument != null && !targetType.getObjectType().isInstance(argument)) { + if (converter == null) { + throw new SpelEvaluationException(SpelMessage.TYPE_CONVERSION_ERROR, argument.getClass().getName(), targetType); + } + arguments[argPosition] = converter.convertValue(argument, TypeDescriptor.forObject(argument), targetType); + } + } + catch (EvaluationException ex) { + // allows for another type converter throwing a different kind of EvaluationException + if (ex instanceof SpelEvaluationException) { + throw (SpelEvaluationException)ex; + } + else { + throw new SpelEvaluationException(ex, SpelMessage.TYPE_CONVERSION_ERROR,arguments[argPosition].getClass().getName(), targetType); + } + } + } + } + + /** + * Package up the arguments so that they correctly match what is expected in parameterTypes. For example, if + * parameterTypes is (int, String[]) because the second parameter was declared String... then if arguments is + * [1,"a","b"] then it must be repackaged as [1,new String[]{"a","b"}] in order to match the expected + * parameterTypes. + * @param requiredParameterTypes the types of the parameters for the invocation + * @param args the arguments to be setup ready for the invocation + * @return a repackaged array of arguments where any varargs setup has been done + */ + public static Object[] setupArgumentsForVarargsInvocation(Class[] requiredParameterTypes, Object... args) { + // Check if array already built for final argument + int parameterCount = requiredParameterTypes.length; + int argumentCount = args.length; + + // Check if repackaging is needed: + if (parameterCount != args.length || + requiredParameterTypes[parameterCount - 1] != + (args[argumentCount - 1] == null ? null : args[argumentCount - 1].getClass())) { + int arraySize = 0; // zero size array if nothing to pass as the varargs parameter + if (argumentCount >= parameterCount) { + arraySize = argumentCount - (parameterCount - 1); + } + + // Create an array for the varargs arguments + Object[] newArgs = new Object[parameterCount]; + for (int i = 0; i < newArgs.length - 1; i++) { + newArgs[i] = args[i]; + } + // Now sort out the final argument, which is the varargs one. Before entering this + // method the arguments should have been converted to the box form of the required type. + Class<?> componentType = requiredParameterTypes[parameterCount-1].getComponentType(); + if (componentType.isPrimitive()) { + if (componentType==Integer.TYPE) { + int[] repackagedArguments = (int[]) Array.newInstance(componentType, arraySize); + for (int i = 0; i < arraySize; i++) { + repackagedArguments[i] = ((Integer)args[parameterCount + i - 1]).intValue(); + } + newArgs[newArgs.length - 1] = repackagedArguments; + } else if(componentType==Float.TYPE) { + float[] repackagedArguments = (float[]) Array.newInstance(componentType, arraySize); + for (int i = 0; i < arraySize; i++) { + repackagedArguments[i] = ((Float)args[parameterCount + i - 1]).floatValue(); + } + newArgs[newArgs.length - 1] = repackagedArguments; + } else if(componentType==Double.TYPE) { + double[] repackagedArguments = (double[]) Array.newInstance(componentType, arraySize); + for (int i = 0; i < arraySize; i++) { + repackagedArguments[i] = ((Double)args[parameterCount + i - 1]).doubleValue(); + } + newArgs[newArgs.length - 1] = repackagedArguments; + } else if(componentType==Short.TYPE) { + short[] repackagedArguments = (short[]) Array.newInstance(componentType, arraySize); + for (int i = 0; i < arraySize; i++) { + repackagedArguments[i] = ((Short)args[parameterCount + i - 1]).shortValue(); + } + newArgs[newArgs.length - 1] = repackagedArguments; + } else if(componentType==Character.TYPE) { + char[] repackagedArguments = (char[]) Array.newInstance(componentType, arraySize); + for (int i = 0; i < arraySize; i++) { + repackagedArguments[i] = ((Character)args[parameterCount + i - 1]).charValue(); + } + newArgs[newArgs.length - 1] = repackagedArguments; + } else if(componentType==Byte.TYPE) { + byte[] repackagedArguments = (byte[]) Array.newInstance(componentType, arraySize); + for (int i = 0; i < arraySize; i++) { + repackagedArguments[i] = ((Byte)args[parameterCount + i - 1]).byteValue(); + } + newArgs[newArgs.length - 1] = repackagedArguments; + } else if(componentType==Boolean.TYPE) { + boolean[] repackagedArguments = (boolean[]) Array.newInstance(componentType, arraySize); + for (int i = 0; i < arraySize; i++) { + repackagedArguments[i] = ((Boolean)args[parameterCount + i - 1]).booleanValue(); + } + newArgs[newArgs.length - 1] = repackagedArguments; + } else if(componentType==Long.TYPE) { + long[] repackagedArguments = (long[]) Array.newInstance(componentType, arraySize); + for (int i = 0; i < arraySize; i++) { + repackagedArguments[i] = ((Long)args[parameterCount + i - 1]).longValue(); + } + newArgs[newArgs.length - 1] = repackagedArguments; + } + } else { + Object[] repackagedArguments = (Object[]) Array.newInstance(componentType, arraySize); + // Copy all but the varargs arguments + for (int i = 0; i < arraySize; i++) { + repackagedArguments[i] = args[parameterCount + i - 1]; + } + newArgs[newArgs.length - 1] = repackagedArguments; + } + return newArgs; + } + return args; + } + + + public static enum ArgsMatchKind { + // An exact match is where the parameter types exactly match what the method/constructor being invoked is expecting + EXACT, + // A close match is where the parameter types either exactly match or are assignment compatible with the method/constructor being invoked + CLOSE, + // A conversion match is where the type converter must be used to transform some of the parameter types + REQUIRES_CONVERSION + } + + + /** + * An instance of ArgumentsMatchInfo describes what kind of match was achieved between two sets of arguments - the set that a + * method/constructor is expecting and the set that are being supplied at the point of invocation. If the kind + * indicates that conversion is required for some of the arguments then the arguments that require conversion are + * listed in the argsRequiringConversion array. + */ + public static class ArgumentsMatchInfo { + + public final ArgsMatchKind kind; + + public int[] argsRequiringConversion; + + ArgumentsMatchInfo(ArgsMatchKind kind, int[] integers) { + this.kind = kind; + this.argsRequiringConversion = integers; + } + + ArgumentsMatchInfo(ArgsMatchKind kind) { + this.kind = kind; + } + + public boolean isExactMatch() { + return (this.kind == ArgsMatchKind.EXACT); + } + + public boolean isCloseMatch() { + return (this.kind == ArgsMatchKind.CLOSE); + } + + public boolean isMatchRequiringConversion() { + return (this.kind == ArgsMatchKind.REQUIRES_CONVERSION); + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("ArgumentMatch: ").append(this.kind); + if (this.argsRequiringConversion != null) { + sb.append(" (argsForConversion:"); + for (int i = 0; i < this.argsRequiringConversion.length;i++) { + if (i > 0) { + sb.append(","); + } + sb.append(this.argsRequiringConversion[i]); + } + sb.append(")"); + } + return sb.toString(); + } + } + +} diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectiveConstructorExecutor.java b/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectiveConstructorExecutor.java index 6623f45f458..6c1d3c5a177 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectiveConstructorExecutor.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectiveConstructorExecutor.java @@ -1,74 +1,74 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.expression.spel.support; - -import java.lang.reflect.Constructor; - -import org.springframework.expression.AccessException; -import org.springframework.expression.ConstructorExecutor; -import org.springframework.expression.EvaluationContext; -import org.springframework.expression.TypedValue; -import org.springframework.util.ReflectionUtils; - -/** - * A simple ConstructorExecutor implementation that runs a constructor using reflective invocation. - * - * @author Andy Clement - * @author Juergen Hoeller - * @since 3.0 - */ -class ReflectiveConstructorExecutor implements ConstructorExecutor { - - private final Constructor<?> ctor; - - private final Integer varargsPosition; - - // When the constructor was found, we will have determined if arguments need to be converted for it - // to be invoked. Conversion won't be cheap so let's only do it if necessary. - private final int[] argsRequiringConversion; - - - public ReflectiveConstructorExecutor(Constructor<?> ctor, int[] argsRequiringConversion) { - this.ctor = ctor; - if (ctor.isVarArgs()) { - Class[] paramTypes = ctor.getParameterTypes(); - this.varargsPosition = paramTypes.length - 1; - } - else { - this.varargsPosition = null; - } - this.argsRequiringConversion = argsRequiringConversion; - } - - public TypedValue execute(EvaluationContext context, Object... arguments) throws AccessException { - try { - if (arguments != null) { - ReflectionHelper.convertArguments(context.getTypeConverter(), arguments, - this.ctor, this.argsRequiringConversion, this.varargsPosition); - } - if (this.ctor.isVarArgs()) { - arguments = ReflectionHelper.setupArgumentsForVarargsInvocation(this.ctor.getParameterTypes(), arguments); - } - ReflectionUtils.makeAccessible(this.ctor); - return new TypedValue(this.ctor.newInstance(arguments)); - } - catch (Exception ex) { - throw new AccessException("Problem invoking constructor: " + this.ctor, ex); - } - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.expression.spel.support; + +import java.lang.reflect.Constructor; + +import org.springframework.expression.AccessException; +import org.springframework.expression.ConstructorExecutor; +import org.springframework.expression.EvaluationContext; +import org.springframework.expression.TypedValue; +import org.springframework.util.ReflectionUtils; + +/** + * A simple ConstructorExecutor implementation that runs a constructor using reflective invocation. + * + * @author Andy Clement + * @author Juergen Hoeller + * @since 3.0 + */ +class ReflectiveConstructorExecutor implements ConstructorExecutor { + + private final Constructor<?> ctor; + + private final Integer varargsPosition; + + // When the constructor was found, we will have determined if arguments need to be converted for it + // to be invoked. Conversion won't be cheap so let's only do it if necessary. + private final int[] argsRequiringConversion; + + + public ReflectiveConstructorExecutor(Constructor<?> ctor, int[] argsRequiringConversion) { + this.ctor = ctor; + if (ctor.isVarArgs()) { + Class[] paramTypes = ctor.getParameterTypes(); + this.varargsPosition = paramTypes.length - 1; + } + else { + this.varargsPosition = null; + } + this.argsRequiringConversion = argsRequiringConversion; + } + + public TypedValue execute(EvaluationContext context, Object... arguments) throws AccessException { + try { + if (arguments != null) { + ReflectionHelper.convertArguments(context.getTypeConverter(), arguments, + this.ctor, this.argsRequiringConversion, this.varargsPosition); + } + if (this.ctor.isVarArgs()) { + arguments = ReflectionHelper.setupArgumentsForVarargsInvocation(this.ctor.getParameterTypes(), arguments); + } + ReflectionUtils.makeAccessible(this.ctor); + return new TypedValue(this.ctor.newInstance(arguments)); + } + catch (Exception ex) { + throw new AccessException("Problem invoking constructor: " + this.ctor, ex); + } + } + +} diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectiveConstructorResolver.java b/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectiveConstructorResolver.java index 91efdd25362..a2768fc0997 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectiveConstructorResolver.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectiveConstructorResolver.java @@ -1,120 +1,120 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.expression.spel.support; - -import java.lang.reflect.Constructor; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; - -import org.springframework.core.MethodParameter; -import org.springframework.core.convert.TypeDescriptor; -import org.springframework.expression.AccessException; -import org.springframework.expression.ConstructorExecutor; -import org.springframework.expression.ConstructorResolver; -import org.springframework.expression.EvaluationContext; -import org.springframework.expression.EvaluationException; -import org.springframework.expression.TypeConverter; - -/** - * A constructor resolver that uses reflection to locate the constructor that should be invoked - * - * @author Andy Clement - * @author Juergen Hoeller - * @since 3.0 - */ -public class ReflectiveConstructorResolver implements ConstructorResolver { - - /** - * Locate a constructor on the type. There are three kinds of match that might occur: - * <ol> - * <li>An exact match where the types of the arguments match the types of the constructor - * <li>An in-exact match where the types we are looking for are subtypes of those defined on the constructor - * <li>A match where we are able to convert the arguments into those expected by the constructor, according to the - * registered type converter. - * </ol> - */ - public ConstructorExecutor resolve(EvaluationContext context, String typename, List<TypeDescriptor> argumentTypes) - throws AccessException { - - try { - TypeConverter typeConverter = context.getTypeConverter(); - Class<?> type = context.getTypeLocator().findType(typename); - Constructor[] ctors = type.getConstructors(); - - Arrays.sort(ctors, new Comparator<Constructor>() { - public int compare(Constructor c1, Constructor c2) { - int c1pl = c1.getParameterTypes().length; - int c2pl = c2.getParameterTypes().length; - return (new Integer(c1pl)).compareTo(c2pl); - } - }); - - Constructor closeMatch = null; - int[] argsToConvert = null; - Constructor matchRequiringConversion = null; - - for (Constructor ctor : ctors) { - Class[] paramTypes = ctor.getParameterTypes(); - List<TypeDescriptor> paramDescriptors = new ArrayList<TypeDescriptor>(paramTypes.length); - for (int i = 0; i < paramTypes.length; i++) { - paramDescriptors.add(new TypeDescriptor(new MethodParameter(ctor, i))); - } - ReflectionHelper.ArgumentsMatchInfo matchInfo = null; - if (ctor.isVarArgs() && argumentTypes.size() >= (paramTypes.length - 1)) { - // *sigh* complicated - // Basically.. we have to have all parameters match up until the varargs one, then the rest of what is - // being provided should be - // the same type whilst the final argument to the method must be an array of that (oh, how easy...not) - - // or the final parameter - // we are supplied does match exactly (it is an array already). - matchInfo = ReflectionHelper.compareArgumentsVarargs(paramDescriptors, argumentTypes, typeConverter); - } - else if (paramTypes.length == argumentTypes.size()) { - // worth a closer look - matchInfo = ReflectionHelper.compareArguments(paramDescriptors, argumentTypes, typeConverter); - } - if (matchInfo != null) { - if (matchInfo.kind == ReflectionHelper.ArgsMatchKind.EXACT) { - return new ReflectiveConstructorExecutor(ctor, null); - } - else if (matchInfo.kind == ReflectionHelper.ArgsMatchKind.CLOSE) { - closeMatch = ctor; - } - else if (matchInfo.kind == ReflectionHelper.ArgsMatchKind.REQUIRES_CONVERSION) { - argsToConvert = matchInfo.argsRequiringConversion; - matchRequiringConversion = ctor; - } - } - } - if (closeMatch != null) { - return new ReflectiveConstructorExecutor(closeMatch, null); - } - else if (matchRequiringConversion != null) { - return new ReflectiveConstructorExecutor(matchRequiringConversion, argsToConvert); - } - else { - return null; - } - } - catch (EvaluationException ex) { - throw new AccessException("Failed to resolve constructor", ex); - } - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.expression.spel.support; + +import java.lang.reflect.Constructor; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; + +import org.springframework.core.MethodParameter; +import org.springframework.core.convert.TypeDescriptor; +import org.springframework.expression.AccessException; +import org.springframework.expression.ConstructorExecutor; +import org.springframework.expression.ConstructorResolver; +import org.springframework.expression.EvaluationContext; +import org.springframework.expression.EvaluationException; +import org.springframework.expression.TypeConverter; + +/** + * A constructor resolver that uses reflection to locate the constructor that should be invoked + * + * @author Andy Clement + * @author Juergen Hoeller + * @since 3.0 + */ +public class ReflectiveConstructorResolver implements ConstructorResolver { + + /** + * Locate a constructor on the type. There are three kinds of match that might occur: + * <ol> + * <li>An exact match where the types of the arguments match the types of the constructor + * <li>An in-exact match where the types we are looking for are subtypes of those defined on the constructor + * <li>A match where we are able to convert the arguments into those expected by the constructor, according to the + * registered type converter. + * </ol> + */ + public ConstructorExecutor resolve(EvaluationContext context, String typename, List<TypeDescriptor> argumentTypes) + throws AccessException { + + try { + TypeConverter typeConverter = context.getTypeConverter(); + Class<?> type = context.getTypeLocator().findType(typename); + Constructor[] ctors = type.getConstructors(); + + Arrays.sort(ctors, new Comparator<Constructor>() { + public int compare(Constructor c1, Constructor c2) { + int c1pl = c1.getParameterTypes().length; + int c2pl = c2.getParameterTypes().length; + return (new Integer(c1pl)).compareTo(c2pl); + } + }); + + Constructor closeMatch = null; + int[] argsToConvert = null; + Constructor matchRequiringConversion = null; + + for (Constructor ctor : ctors) { + Class[] paramTypes = ctor.getParameterTypes(); + List<TypeDescriptor> paramDescriptors = new ArrayList<TypeDescriptor>(paramTypes.length); + for (int i = 0; i < paramTypes.length; i++) { + paramDescriptors.add(new TypeDescriptor(new MethodParameter(ctor, i))); + } + ReflectionHelper.ArgumentsMatchInfo matchInfo = null; + if (ctor.isVarArgs() && argumentTypes.size() >= (paramTypes.length - 1)) { + // *sigh* complicated + // Basically.. we have to have all parameters match up until the varargs one, then the rest of what is + // being provided should be + // the same type whilst the final argument to the method must be an array of that (oh, how easy...not) - + // or the final parameter + // we are supplied does match exactly (it is an array already). + matchInfo = ReflectionHelper.compareArgumentsVarargs(paramDescriptors, argumentTypes, typeConverter); + } + else if (paramTypes.length == argumentTypes.size()) { + // worth a closer look + matchInfo = ReflectionHelper.compareArguments(paramDescriptors, argumentTypes, typeConverter); + } + if (matchInfo != null) { + if (matchInfo.kind == ReflectionHelper.ArgsMatchKind.EXACT) { + return new ReflectiveConstructorExecutor(ctor, null); + } + else if (matchInfo.kind == ReflectionHelper.ArgsMatchKind.CLOSE) { + closeMatch = ctor; + } + else if (matchInfo.kind == ReflectionHelper.ArgsMatchKind.REQUIRES_CONVERSION) { + argsToConvert = matchInfo.argsRequiringConversion; + matchRequiringConversion = ctor; + } + } + } + if (closeMatch != null) { + return new ReflectiveConstructorExecutor(closeMatch, null); + } + else if (matchRequiringConversion != null) { + return new ReflectiveConstructorExecutor(matchRequiringConversion, argsToConvert); + } + else { + return null; + } + } + catch (EvaluationException ex) { + throw new AccessException("Failed to resolve constructor", ex); + } + } + +} diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectiveMethodExecutor.java b/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectiveMethodExecutor.java index f12cb28a6d6..a54dbac7bc0 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectiveMethodExecutor.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectiveMethodExecutor.java @@ -1,77 +1,77 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.expression.spel.support; - -import java.lang.reflect.Method; - -import org.springframework.core.MethodParameter; -import org.springframework.core.convert.TypeDescriptor; -import org.springframework.expression.AccessException; -import org.springframework.expression.EvaluationContext; -import org.springframework.expression.MethodExecutor; -import org.springframework.expression.TypedValue; -import org.springframework.util.ReflectionUtils; - -/** - * @author Andy Clement - * @author Juergen Hoeller - * @since 3.0 - */ -class ReflectiveMethodExecutor implements MethodExecutor { - - private final Method method; - - private final Integer varargsPosition; - - // When the method was found, we will have determined if arguments need to be converted for it - // to be invoked. Conversion won't be cheap so let's only do it if necessary. - private final int[] argsRequiringConversion; - - - public ReflectiveMethodExecutor(Method theMethod, int[] argumentsRequiringConversion) { - this.method = theMethod; - if (theMethod.isVarArgs()) { - Class[] paramTypes = theMethod.getParameterTypes(); - this.varargsPosition = paramTypes.length - 1; - } - else { - this.varargsPosition = null; - } - this.argsRequiringConversion = argumentsRequiringConversion; - } - - - public TypedValue execute(EvaluationContext context, Object target, Object... arguments) throws AccessException { - try { - if (arguments != null) { - ReflectionHelper.convertArguments( - context.getTypeConverter(), arguments, this.method, - this.argsRequiringConversion, this.varargsPosition); - } - if (this.method.isVarArgs()) { - arguments = ReflectionHelper.setupArgumentsForVarargsInvocation(this.method.getParameterTypes(), arguments); - } - ReflectionUtils.makeAccessible(this.method); - Object value = this.method.invoke(target, arguments); - return new TypedValue(value, new TypeDescriptor(new MethodParameter(this.method, -1)).narrow(value)); - } - catch (Exception ex) { - throw new AccessException("Problem invoking method: " + this.method, ex); - } - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.expression.spel.support; + +import java.lang.reflect.Method; + +import org.springframework.core.MethodParameter; +import org.springframework.core.convert.TypeDescriptor; +import org.springframework.expression.AccessException; +import org.springframework.expression.EvaluationContext; +import org.springframework.expression.MethodExecutor; +import org.springframework.expression.TypedValue; +import org.springframework.util.ReflectionUtils; + +/** + * @author Andy Clement + * @author Juergen Hoeller + * @since 3.0 + */ +class ReflectiveMethodExecutor implements MethodExecutor { + + private final Method method; + + private final Integer varargsPosition; + + // When the method was found, we will have determined if arguments need to be converted for it + // to be invoked. Conversion won't be cheap so let's only do it if necessary. + private final int[] argsRequiringConversion; + + + public ReflectiveMethodExecutor(Method theMethod, int[] argumentsRequiringConversion) { + this.method = theMethod; + if (theMethod.isVarArgs()) { + Class[] paramTypes = theMethod.getParameterTypes(); + this.varargsPosition = paramTypes.length - 1; + } + else { + this.varargsPosition = null; + } + this.argsRequiringConversion = argumentsRequiringConversion; + } + + + public TypedValue execute(EvaluationContext context, Object target, Object... arguments) throws AccessException { + try { + if (arguments != null) { + ReflectionHelper.convertArguments( + context.getTypeConverter(), arguments, this.method, + this.argsRequiringConversion, this.varargsPosition); + } + if (this.method.isVarArgs()) { + arguments = ReflectionHelper.setupArgumentsForVarargsInvocation(this.method.getParameterTypes(), arguments); + } + ReflectionUtils.makeAccessible(this.method); + Object value = this.method.invoke(target, arguments); + return new TypedValue(value, new TypeDescriptor(new MethodParameter(this.method, -1)).narrow(value)); + } + catch (Exception ex) { + throw new AccessException("Problem invoking method: " + this.method, ex); + } + } + +} diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectiveMethodResolver.java b/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectiveMethodResolver.java index c606e854fa6..d40daa3cbae 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectiveMethodResolver.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectiveMethodResolver.java @@ -1,197 +1,197 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.expression.spel.support; - -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.springframework.core.MethodParameter; -import org.springframework.core.convert.TypeDescriptor; -import org.springframework.expression.AccessException; -import org.springframework.expression.EvaluationContext; -import org.springframework.expression.EvaluationException; -import org.springframework.expression.MethodExecutor; -import org.springframework.expression.MethodFilter; -import org.springframework.expression.MethodResolver; -import org.springframework.expression.TypeConverter; -import org.springframework.expression.spel.SpelEvaluationException; -import org.springframework.expression.spel.SpelMessage; -import org.springframework.util.CollectionUtils; - -/** - * A method resolver that uses reflection to locate the method that should be invoked. - * - * @author Andy Clement - * @author Juergen Hoeller - * @since 3.0 - */ -public class ReflectiveMethodResolver implements MethodResolver { - - private static Method[] NO_METHODS = new Method[0]; - - private Map<Class<?>, MethodFilter> filters = null; - - // Using distance will ensure a more accurate match is discovered, - // more closely following the Java rules. - private boolean useDistance = false; - - - public ReflectiveMethodResolver() { - - } - - /** - * This constructors allows the ReflectiveMethodResolver to be configured such that it will - * use a distance computation to check which is the better of two close matches (when there - * are multiple matches). Using the distance computation is intended to ensure matches - * are more closely representative of what a Java compiler would do when taking into - * account boxing/unboxing and whether the method candidates are declared to handle a - * supertype of the type (of the argument) being passed in. - * @param useDistance true if distance computation should be used when calculating matches - */ - public ReflectiveMethodResolver(boolean useDistance) { - this.useDistance = useDistance; - } - - /** - * Locate a method on a type. There are three kinds of match that might occur: - * <ol> - * <li>An exact match where the types of the arguments match the types of the constructor - * <li>An in-exact match where the types we are looking for are subtypes of those defined on the constructor - * <li>A match where we are able to convert the arguments into those expected by the constructor, - * according to the registered type converter. - * </ol> - */ - public MethodExecutor resolve(EvaluationContext context, Object targetObject, String name, - List<TypeDescriptor> argumentTypes) throws AccessException { - - try { - TypeConverter typeConverter = context.getTypeConverter(); - Class<?> type = (targetObject instanceof Class ? (Class<?>) targetObject : targetObject.getClass()); - Method[] methods = type.getMethods(); - - // If a filter is registered for this type, call it - MethodFilter filter = (this.filters != null ? this.filters.get(type) : null); - if (filter != null) { - List<Method> methodsForFiltering = new ArrayList<Method>(); - for (Method method: methods) { - methodsForFiltering.add(method); - } - List<Method> methodsFiltered = filter.filter(methodsForFiltering); - if (CollectionUtils.isEmpty(methodsFiltered)) { - methods = NO_METHODS; - } - else { - methods = methodsFiltered.toArray(new Method[methodsFiltered.size()]); - } - } - - Arrays.sort(methods, new Comparator<Method>() { - public int compare(Method m1, Method m2) { - int m1pl = m1.getParameterTypes().length; - int m2pl = m2.getParameterTypes().length; - return (new Integer(m1pl)).compareTo(m2pl); - } - }); - - Method closeMatch = null; - int closeMatchDistance = Integer.MAX_VALUE; - int[] argsToConvert = null; - Method matchRequiringConversion = null; - boolean multipleOptions = false; - - for (Method method : methods) { - if (method.isBridge()) { - continue; - } - if (method.getName().equals(name)) { - Class[] paramTypes = method.getParameterTypes(); - List<TypeDescriptor> paramDescriptors = new ArrayList<TypeDescriptor>(paramTypes.length); - for (int i = 0; i < paramTypes.length; i++) { - paramDescriptors.add(new TypeDescriptor(new MethodParameter(method, i))); - } - ReflectionHelper.ArgumentsMatchInfo matchInfo = null; - if (method.isVarArgs() && argumentTypes.size() >= (paramTypes.length - 1)) { - // *sigh* complicated - matchInfo = ReflectionHelper.compareArgumentsVarargs(paramDescriptors, argumentTypes, typeConverter); - } - else if (paramTypes.length == argumentTypes.size()) { - // name and parameter number match, check the arguments - matchInfo = ReflectionHelper.compareArguments(paramDescriptors, argumentTypes, typeConverter); - } - if (matchInfo != null) { - if (matchInfo.kind == ReflectionHelper.ArgsMatchKind.EXACT) { - return new ReflectiveMethodExecutor(method, null); - } - else if (matchInfo.kind == ReflectionHelper.ArgsMatchKind.CLOSE) { - if (!useDistance) { - closeMatch = method; - } else { - int matchDistance = ReflectionHelper.getTypeDifferenceWeight(paramDescriptors, argumentTypes); - if (matchDistance<closeMatchDistance) { - // this is a better match - closeMatchDistance = matchDistance; - closeMatch = method; - } - } - } - else if (matchInfo.kind == ReflectionHelper.ArgsMatchKind.REQUIRES_CONVERSION) { - if (matchRequiringConversion != null) { - multipleOptions = true; - } - argsToConvert = matchInfo.argsRequiringConversion; - matchRequiringConversion = method; - } - } - } - } - if (closeMatch != null) { - return new ReflectiveMethodExecutor(closeMatch, null); - } - else if (matchRequiringConversion != null) { - if (multipleOptions) { - throw new SpelEvaluationException(SpelMessage.MULTIPLE_POSSIBLE_METHODS, name); - } - return new ReflectiveMethodExecutor(matchRequiringConversion, argsToConvert); - } - else { - return null; - } - } - catch (EvaluationException ex) { - throw new AccessException("Failed to resolve method", ex); - } - } - - public void registerMethodFilter(Class<?> type, MethodFilter filter) { - if (this.filters == null) { - this.filters = new HashMap<Class<?>, MethodFilter>(); - } - if (filter == null) { - this.filters.remove(type); - } - else { - this.filters.put(type,filter); - } - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.expression.spel.support; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.springframework.core.MethodParameter; +import org.springframework.core.convert.TypeDescriptor; +import org.springframework.expression.AccessException; +import org.springframework.expression.EvaluationContext; +import org.springframework.expression.EvaluationException; +import org.springframework.expression.MethodExecutor; +import org.springframework.expression.MethodFilter; +import org.springframework.expression.MethodResolver; +import org.springframework.expression.TypeConverter; +import org.springframework.expression.spel.SpelEvaluationException; +import org.springframework.expression.spel.SpelMessage; +import org.springframework.util.CollectionUtils; + +/** + * A method resolver that uses reflection to locate the method that should be invoked. + * + * @author Andy Clement + * @author Juergen Hoeller + * @since 3.0 + */ +public class ReflectiveMethodResolver implements MethodResolver { + + private static Method[] NO_METHODS = new Method[0]; + + private Map<Class<?>, MethodFilter> filters = null; + + // Using distance will ensure a more accurate match is discovered, + // more closely following the Java rules. + private boolean useDistance = false; + + + public ReflectiveMethodResolver() { + + } + + /** + * This constructors allows the ReflectiveMethodResolver to be configured such that it will + * use a distance computation to check which is the better of two close matches (when there + * are multiple matches). Using the distance computation is intended to ensure matches + * are more closely representative of what a Java compiler would do when taking into + * account boxing/unboxing and whether the method candidates are declared to handle a + * supertype of the type (of the argument) being passed in. + * @param useDistance true if distance computation should be used when calculating matches + */ + public ReflectiveMethodResolver(boolean useDistance) { + this.useDistance = useDistance; + } + + /** + * Locate a method on a type. There are three kinds of match that might occur: + * <ol> + * <li>An exact match where the types of the arguments match the types of the constructor + * <li>An in-exact match where the types we are looking for are subtypes of those defined on the constructor + * <li>A match where we are able to convert the arguments into those expected by the constructor, + * according to the registered type converter. + * </ol> + */ + public MethodExecutor resolve(EvaluationContext context, Object targetObject, String name, + List<TypeDescriptor> argumentTypes) throws AccessException { + + try { + TypeConverter typeConverter = context.getTypeConverter(); + Class<?> type = (targetObject instanceof Class ? (Class<?>) targetObject : targetObject.getClass()); + Method[] methods = type.getMethods(); + + // If a filter is registered for this type, call it + MethodFilter filter = (this.filters != null ? this.filters.get(type) : null); + if (filter != null) { + List<Method> methodsForFiltering = new ArrayList<Method>(); + for (Method method: methods) { + methodsForFiltering.add(method); + } + List<Method> methodsFiltered = filter.filter(methodsForFiltering); + if (CollectionUtils.isEmpty(methodsFiltered)) { + methods = NO_METHODS; + } + else { + methods = methodsFiltered.toArray(new Method[methodsFiltered.size()]); + } + } + + Arrays.sort(methods, new Comparator<Method>() { + public int compare(Method m1, Method m2) { + int m1pl = m1.getParameterTypes().length; + int m2pl = m2.getParameterTypes().length; + return (new Integer(m1pl)).compareTo(m2pl); + } + }); + + Method closeMatch = null; + int closeMatchDistance = Integer.MAX_VALUE; + int[] argsToConvert = null; + Method matchRequiringConversion = null; + boolean multipleOptions = false; + + for (Method method : methods) { + if (method.isBridge()) { + continue; + } + if (method.getName().equals(name)) { + Class[] paramTypes = method.getParameterTypes(); + List<TypeDescriptor> paramDescriptors = new ArrayList<TypeDescriptor>(paramTypes.length); + for (int i = 0; i < paramTypes.length; i++) { + paramDescriptors.add(new TypeDescriptor(new MethodParameter(method, i))); + } + ReflectionHelper.ArgumentsMatchInfo matchInfo = null; + if (method.isVarArgs() && argumentTypes.size() >= (paramTypes.length - 1)) { + // *sigh* complicated + matchInfo = ReflectionHelper.compareArgumentsVarargs(paramDescriptors, argumentTypes, typeConverter); + } + else if (paramTypes.length == argumentTypes.size()) { + // name and parameter number match, check the arguments + matchInfo = ReflectionHelper.compareArguments(paramDescriptors, argumentTypes, typeConverter); + } + if (matchInfo != null) { + if (matchInfo.kind == ReflectionHelper.ArgsMatchKind.EXACT) { + return new ReflectiveMethodExecutor(method, null); + } + else if (matchInfo.kind == ReflectionHelper.ArgsMatchKind.CLOSE) { + if (!useDistance) { + closeMatch = method; + } else { + int matchDistance = ReflectionHelper.getTypeDifferenceWeight(paramDescriptors, argumentTypes); + if (matchDistance<closeMatchDistance) { + // this is a better match + closeMatchDistance = matchDistance; + closeMatch = method; + } + } + } + else if (matchInfo.kind == ReflectionHelper.ArgsMatchKind.REQUIRES_CONVERSION) { + if (matchRequiringConversion != null) { + multipleOptions = true; + } + argsToConvert = matchInfo.argsRequiringConversion; + matchRequiringConversion = method; + } + } + } + } + if (closeMatch != null) { + return new ReflectiveMethodExecutor(closeMatch, null); + } + else if (matchRequiringConversion != null) { + if (multipleOptions) { + throw new SpelEvaluationException(SpelMessage.MULTIPLE_POSSIBLE_METHODS, name); + } + return new ReflectiveMethodExecutor(matchRequiringConversion, argsToConvert); + } + else { + return null; + } + } + catch (EvaluationException ex) { + throw new AccessException("Failed to resolve method", ex); + } + } + + public void registerMethodFilter(Class<?> type, MethodFilter filter) { + if (this.filters == null) { + this.filters = new HashMap<Class<?>, MethodFilter>(); + } + if (filter == null) { + this.filters.remove(type); + } + else { + this.filters.put(type,filter); + } + } + +} diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java b/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java index e6cd3740827..621db0ec376 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java @@ -1,527 +1,527 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.expression.spel.support; - -import java.lang.reflect.Array; -import java.lang.reflect.Field; -import java.lang.reflect.Member; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import org.springframework.core.MethodParameter; -import org.springframework.core.convert.Property; -import org.springframework.core.convert.TypeDescriptor; -import org.springframework.expression.AccessException; -import org.springframework.expression.EvaluationContext; -import org.springframework.expression.EvaluationException; -import org.springframework.expression.PropertyAccessor; -import org.springframework.expression.TypedValue; -import org.springframework.util.ReflectionUtils; -import org.springframework.util.StringUtils; - -/** - * Simple PropertyAccessor that uses reflection to access properties for reading and writing. A property can be accessed - * if it is accessible as a field on the object or through a getter (if being read) or a setter (if being written). - * - * @author Andy Clement - * @author Juergen Hoeller - * @since 3.0 - */ -public class ReflectivePropertyAccessor implements PropertyAccessor { - - protected final Map<CacheKey, InvokerPair> readerCache = new ConcurrentHashMap<CacheKey, InvokerPair>(); - - protected final Map<CacheKey, Member> writerCache = new ConcurrentHashMap<CacheKey, Member>(); - - protected final Map<CacheKey, TypeDescriptor> typeDescriptorCache = new ConcurrentHashMap<CacheKey, TypeDescriptor>(); - - - /** - * @return null which means this is a general purpose accessor - */ - public Class<?>[] getSpecificTargetClasses() { - return null; - } - - public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException { - if (target == null) { - return false; - } - Class<?> type = (target instanceof Class ? (Class<?>) target : target.getClass()); - if (type.isArray() && name.equals("length")) { - return true; - } - CacheKey cacheKey = new CacheKey(type, name); - if (this.readerCache.containsKey(cacheKey)) { - return true; - } - Method method = findGetterForProperty(name, type, target instanceof Class); - if (method != null) { - // Treat it like a property - // The readerCache will only contain gettable properties (let's not worry about setters for now) - Property property = new Property(type, method, null); - TypeDescriptor typeDescriptor = new TypeDescriptor(property); - this.readerCache.put(cacheKey, new InvokerPair(method, typeDescriptor)); - this.typeDescriptorCache.put(cacheKey, typeDescriptor); - return true; - } - else { - Field field = findField(name, type, target instanceof Class); - if (field != null) { - TypeDescriptor typeDescriptor = new TypeDescriptor(field); - this.readerCache.put(cacheKey, new InvokerPair(field,typeDescriptor)); - this.typeDescriptorCache.put(cacheKey, typeDescriptor); - return true; - } - } - return false; - } - - public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException { - if (target == null) { - throw new AccessException("Cannot read property of null target"); - } - Class<?> type = (target instanceof Class ? (Class<?>) target : target.getClass()); - - if (type.isArray() && name.equals("length")) { - if (target instanceof Class) { - throw new AccessException("Cannot access length on array class itself"); - } - return new TypedValue(Array.getLength(target)); - } - - CacheKey cacheKey = new CacheKey(type, name); - InvokerPair invoker = this.readerCache.get(cacheKey); - - if (invoker == null || invoker.member instanceof Method) { - Method method = (Method) (invoker != null ? invoker.member : null); - if (method == null) { - method = findGetterForProperty(name, type, target instanceof Class); - if (method != null) { - // TODO remove the duplication here between canRead and read - // Treat it like a property - // The readerCache will only contain gettable properties (let's not worry about setters for now) - Property property = new Property(type, method, null); - TypeDescriptor typeDescriptor = new TypeDescriptor(property); - invoker = new InvokerPair(method, typeDescriptor); - this.readerCache.put(cacheKey, invoker); - } - } - if (method != null) { - try { - ReflectionUtils.makeAccessible(method); - Object value = method.invoke(target); - return new TypedValue(value, invoker.typeDescriptor.narrow(value)); - } - catch (Exception ex) { - throw new AccessException("Unable to access property '" + name + "' through getter", ex); - } - } - } - - if (invoker == null || invoker.member instanceof Field) { - Field field = (Field) (invoker == null ? null : invoker.member); - if (field == null) { - field = findField(name, type, target instanceof Class); - if (field != null) { - invoker = new InvokerPair(field, new TypeDescriptor(field)); - this.readerCache.put(cacheKey, invoker); - } - } - if (field != null) { - try { - ReflectionUtils.makeAccessible(field); - Object value = field.get(target); - return new TypedValue(value, invoker.typeDescriptor.narrow(value)); - } - catch (Exception ex) { - throw new AccessException("Unable to access field: " + name, ex); - } - } - } - - throw new AccessException("Neither getter nor field found for property '" + name + "'"); - } - - public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException { - if (target == null) { - return false; - } - Class<?> type = (target instanceof Class ? (Class<?>) target : target.getClass()); - CacheKey cacheKey = new CacheKey(type, name); - if (this.writerCache.containsKey(cacheKey)) { - return true; - } - Method method = findSetterForProperty(name, type, target instanceof Class); - if (method != null) { - // Treat it like a property - Property property = new Property(type, null, method); - TypeDescriptor typeDescriptor = new TypeDescriptor(property); - this.writerCache.put(cacheKey, method); - this.typeDescriptorCache.put(cacheKey, typeDescriptor); - return true; - } - else { - Field field = findField(name, type, target instanceof Class); - if (field != null) { - this.writerCache.put(cacheKey, field); - this.typeDescriptorCache.put(cacheKey, new TypeDescriptor(field)); - return true; - } - } - return false; - } - - public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException { - if (target == null) { - throw new AccessException("Cannot write property on null target"); - } - Class<?> type = (target instanceof Class ? (Class<?>) target : target.getClass()); - - Object possiblyConvertedNewValue = newValue; - TypeDescriptor typeDescriptor = getTypeDescriptor(context, target, name); - if (typeDescriptor != null) { - try { - possiblyConvertedNewValue = context.getTypeConverter().convertValue( - newValue, TypeDescriptor.forObject(newValue), typeDescriptor); - } - catch (EvaluationException evaluationException) { - throw new AccessException("Type conversion failure",evaluationException); - } - } - CacheKey cacheKey = new CacheKey(type, name); - Member cachedMember = this.writerCache.get(cacheKey); - - if (cachedMember == null || cachedMember instanceof Method) { - Method method = (Method) cachedMember; - if (method == null) { - method = findSetterForProperty(name, type, target instanceof Class); - if (method != null) { - cachedMember = method; - this.writerCache.put(cacheKey, cachedMember); - } - } - if (method != null) { - try { - ReflectionUtils.makeAccessible(method); - method.invoke(target, possiblyConvertedNewValue); - return; - } - catch (Exception ex) { - throw new AccessException("Unable to access property '" + name + "' through setter", ex); - } - } - } - - if (cachedMember == null || cachedMember instanceof Field) { - Field field = (Field) cachedMember; - if (field == null) { - field = findField(name, type, target instanceof Class); - if (field != null) { - cachedMember = field; - this.writerCache.put(cacheKey, cachedMember); - } - } - if (field != null) { - try { - ReflectionUtils.makeAccessible(field); - field.set(target, possiblyConvertedNewValue); - return; - } - catch (Exception ex) { - throw new AccessException("Unable to access field: " + name, ex); - } - } - } - - throw new AccessException("Neither setter nor field found for property '" + name + "'"); - } - - private TypeDescriptor getTypeDescriptor(EvaluationContext context, Object target, String name) { - if (target == null) { - return null; - } - Class<?> type = (target instanceof Class ? (Class<?>) target : target.getClass()); - - if (type.isArray() && name.equals("length")) { - return TypeDescriptor.valueOf(Integer.TYPE); - } - CacheKey cacheKey = new CacheKey(type, name); - TypeDescriptor typeDescriptor = this.typeDescriptorCache.get(cacheKey); - if (typeDescriptor == null) { - // attempt to populate the cache entry - try { - if (canRead(context, target, name)) { - typeDescriptor = this.typeDescriptorCache.get(cacheKey); - } - else if (canWrite(context, target, name)) { - typeDescriptor = this.typeDescriptorCache.get(cacheKey); - } - } - catch (AccessException ex) { - // continue with null type descriptor - } - } - return typeDescriptor; - } - - /** - * Find a getter method for the specified property. A getter is defined as a method whose name start with the prefix - * 'get' and the rest of the name is the same as the property name (with the first character uppercased). - */ - protected Method findGetterForProperty(String propertyName, Class<?> clazz, boolean mustBeStatic) { - Method[] ms = clazz.getMethods(); - // Try "get*" method... - String getterName = "get" + StringUtils.capitalize(propertyName); - for (Method method : ms) { - if (method.getName().equals(getterName) && method.getParameterTypes().length == 0 && - (!mustBeStatic || Modifier.isStatic(method.getModifiers()))) { - return method; - } - } - // Try "is*" method... - getterName = "is" + StringUtils.capitalize(propertyName); - for (Method method : ms) { - if (method.getName().equals(getterName) && method.getParameterTypes().length == 0 && - boolean.class.equals(method.getReturnType()) && - (!mustBeStatic || Modifier.isStatic(method.getModifiers()))) { - return method; - } - } - return null; - } - - /** - * Find a setter method for the specified property. - */ - protected Method findSetterForProperty(String propertyName, Class<?> clazz, boolean mustBeStatic) { - Method[] methods = clazz.getMethods(); - String setterName = "set" + StringUtils.capitalize(propertyName); - for (Method method : methods) { - if (method.getName().equals(setterName) && method.getParameterTypes().length == 1 && - (!mustBeStatic || Modifier.isStatic(method.getModifiers()))) { - return method; - } - } - return null; - } - - /** - * Find a field of a certain name on a specified class - */ - protected Field findField(String name, Class<?> clazz, boolean mustBeStatic) { - Field[] fields = clazz.getFields(); - for (Field field : fields) { - if (field.getName().equals(name) && (!mustBeStatic || Modifier.isStatic(field.getModifiers()))) { - return field; - } - } - return null; - } - - /** - * Captures the member (method/field) to call reflectively to access a property value and the type descriptor for the - * value returned by the reflective call. - */ - private static class InvokerPair { - - final Member member; - - final TypeDescriptor typeDescriptor; - - public InvokerPair(Member member, TypeDescriptor typeDescriptor) { - this.member = member; - this.typeDescriptor = typeDescriptor; - } - - } - - private static class CacheKey { - - private final Class clazz; - - private final String name; - - public CacheKey(Class clazz, String name) { - this.clazz = clazz; - this.name = name; - } - - @Override - public boolean equals(Object other) { - if (this == other) { - return true; - } - if (!(other instanceof CacheKey)) { - return false; - } - CacheKey otherKey = (CacheKey) other; - return (this.clazz.equals(otherKey.clazz) && this.name.equals(otherKey.name)); - } - - @Override - public int hashCode() { - return this.clazz.hashCode() * 29 + this.name.hashCode(); - } - } - - /** - * Attempt to create an optimized property accessor tailored for a property of a particular name on - * a particular class. The general ReflectivePropertyAccessor will always work but is not optimal - * due to the need to lookup which reflective member (method/field) to use each time read() is called. - * This method will just return the ReflectivePropertyAccessor instance if it is unable to build - * something more optimal. - */ - public PropertyAccessor createOptimalAccessor(EvaluationContext eContext, Object target, String name) { - // Don't be clever for arrays or null target - if (target == null) { - return this; - } - Class<?> type = (target instanceof Class ? (Class<?>) target : target.getClass()); - if (type.isArray()) { - return this; - } - - CacheKey cacheKey = new CacheKey(type, name); - InvokerPair invocationTarget = this.readerCache.get(cacheKey); - - if (invocationTarget == null || invocationTarget.member instanceof Method) { - Method method = (Method) (invocationTarget==null?null:invocationTarget.member); - if (method == null) { - method = findGetterForProperty(name, type, target instanceof Class); - if (method != null) { - invocationTarget = new InvokerPair(method,new TypeDescriptor(new MethodParameter(method,-1))); - ReflectionUtils.makeAccessible(method); - this.readerCache.put(cacheKey, invocationTarget); - } - } - if (method != null) { - return new OptimalPropertyAccessor(invocationTarget); - } - } - - if (invocationTarget == null || invocationTarget.member instanceof Field) { - Field field = (Field) (invocationTarget==null?null:invocationTarget.member); - if (field == null) { - field = findField(name, type, target instanceof Class); - if (field != null) { - invocationTarget = new InvokerPair(field, new TypeDescriptor(field)); - ReflectionUtils.makeAccessible(field); - this.readerCache.put(cacheKey, invocationTarget); - } - } - if (field != null) { - return new OptimalPropertyAccessor(invocationTarget); - } - } - return this; - } - - /** - * An optimized form of a PropertyAccessor that will use reflection but only knows how to access a particular property - * on a particular class. This is unlike the general ReflectivePropertyResolver which manages a cache of methods/fields that - * may be invoked to access different properties on different classes. This optimal accessor exists because looking up - * the appropriate reflective object by class/name on each read is not cheap. - */ - static class OptimalPropertyAccessor implements PropertyAccessor { - private final Member member; - private final TypeDescriptor typeDescriptor; - private final boolean needsToBeMadeAccessible; - - OptimalPropertyAccessor(InvokerPair target) { - this.member = target.member; - this.typeDescriptor = target.typeDescriptor; - if (this.member instanceof Field) { - Field field = (Field)member; - needsToBeMadeAccessible = (!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers())) - && !field.isAccessible(); - } - else { - Method method = (Method)member; - needsToBeMadeAccessible = ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers())) - && !method.isAccessible()); - } - } - - public Class[] getSpecificTargetClasses() { - throw new UnsupportedOperationException("Should not be called on an OptimalPropertyAccessor"); - } - - public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException { - if (target == null) { - return false; - } - Class<?> type = (target instanceof Class ? (Class<?>) target : target.getClass()); - if (type.isArray()) { - return false; - } - if (member instanceof Method) { - Method method = (Method)member; - String getterName = "get" + StringUtils.capitalize(name); - if (getterName.equals(method.getName())) { - return true; - } - getterName = "is" + StringUtils.capitalize(name); - return getterName.equals(method.getName()); - } - else { - Field field = (Field)member; - return field.getName().equals(name); - } - } - - public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException { - if (member instanceof Method) { - try { - if (needsToBeMadeAccessible) { - ReflectionUtils.makeAccessible((Method) member); - } - Object value = ((Method) member).invoke(target); - return new TypedValue(value, typeDescriptor.narrow(value)); - } - catch (Exception ex) { - throw new AccessException("Unable to access property '" + name + "' through getter", ex); - } - } - if (member instanceof Field) { - try { - if (needsToBeMadeAccessible) { - ReflectionUtils.makeAccessible((Field)member); - } - Object value = ((Field)member).get(target); - return new TypedValue(value, typeDescriptor.narrow(value)); - } - catch (Exception ex) { - throw new AccessException("Unable to access field: " + name, ex); - } - } - throw new AccessException("Neither getter nor field found for property '" + name + "'"); - } - - public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException { - throw new UnsupportedOperationException("Should not be called on an OptimalPropertyAccessor"); - } - - public void write(EvaluationContext context, Object target, String name, Object newValue) - throws AccessException { - throw new UnsupportedOperationException("Should not be called on an OptimalPropertyAccessor"); - } - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.expression.spel.support; + +import java.lang.reflect.Array; +import java.lang.reflect.Field; +import java.lang.reflect.Member; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.springframework.core.MethodParameter; +import org.springframework.core.convert.Property; +import org.springframework.core.convert.TypeDescriptor; +import org.springframework.expression.AccessException; +import org.springframework.expression.EvaluationContext; +import org.springframework.expression.EvaluationException; +import org.springframework.expression.PropertyAccessor; +import org.springframework.expression.TypedValue; +import org.springframework.util.ReflectionUtils; +import org.springframework.util.StringUtils; + +/** + * Simple PropertyAccessor that uses reflection to access properties for reading and writing. A property can be accessed + * if it is accessible as a field on the object or through a getter (if being read) or a setter (if being written). + * + * @author Andy Clement + * @author Juergen Hoeller + * @since 3.0 + */ +public class ReflectivePropertyAccessor implements PropertyAccessor { + + protected final Map<CacheKey, InvokerPair> readerCache = new ConcurrentHashMap<CacheKey, InvokerPair>(); + + protected final Map<CacheKey, Member> writerCache = new ConcurrentHashMap<CacheKey, Member>(); + + protected final Map<CacheKey, TypeDescriptor> typeDescriptorCache = new ConcurrentHashMap<CacheKey, TypeDescriptor>(); + + + /** + * @return null which means this is a general purpose accessor + */ + public Class<?>[] getSpecificTargetClasses() { + return null; + } + + public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException { + if (target == null) { + return false; + } + Class<?> type = (target instanceof Class ? (Class<?>) target : target.getClass()); + if (type.isArray() && name.equals("length")) { + return true; + } + CacheKey cacheKey = new CacheKey(type, name); + if (this.readerCache.containsKey(cacheKey)) { + return true; + } + Method method = findGetterForProperty(name, type, target instanceof Class); + if (method != null) { + // Treat it like a property + // The readerCache will only contain gettable properties (let's not worry about setters for now) + Property property = new Property(type, method, null); + TypeDescriptor typeDescriptor = new TypeDescriptor(property); + this.readerCache.put(cacheKey, new InvokerPair(method, typeDescriptor)); + this.typeDescriptorCache.put(cacheKey, typeDescriptor); + return true; + } + else { + Field field = findField(name, type, target instanceof Class); + if (field != null) { + TypeDescriptor typeDescriptor = new TypeDescriptor(field); + this.readerCache.put(cacheKey, new InvokerPair(field,typeDescriptor)); + this.typeDescriptorCache.put(cacheKey, typeDescriptor); + return true; + } + } + return false; + } + + public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException { + if (target == null) { + throw new AccessException("Cannot read property of null target"); + } + Class<?> type = (target instanceof Class ? (Class<?>) target : target.getClass()); + + if (type.isArray() && name.equals("length")) { + if (target instanceof Class) { + throw new AccessException("Cannot access length on array class itself"); + } + return new TypedValue(Array.getLength(target)); + } + + CacheKey cacheKey = new CacheKey(type, name); + InvokerPair invoker = this.readerCache.get(cacheKey); + + if (invoker == null || invoker.member instanceof Method) { + Method method = (Method) (invoker != null ? invoker.member : null); + if (method == null) { + method = findGetterForProperty(name, type, target instanceof Class); + if (method != null) { + // TODO remove the duplication here between canRead and read + // Treat it like a property + // The readerCache will only contain gettable properties (let's not worry about setters for now) + Property property = new Property(type, method, null); + TypeDescriptor typeDescriptor = new TypeDescriptor(property); + invoker = new InvokerPair(method, typeDescriptor); + this.readerCache.put(cacheKey, invoker); + } + } + if (method != null) { + try { + ReflectionUtils.makeAccessible(method); + Object value = method.invoke(target); + return new TypedValue(value, invoker.typeDescriptor.narrow(value)); + } + catch (Exception ex) { + throw new AccessException("Unable to access property '" + name + "' through getter", ex); + } + } + } + + if (invoker == null || invoker.member instanceof Field) { + Field field = (Field) (invoker == null ? null : invoker.member); + if (field == null) { + field = findField(name, type, target instanceof Class); + if (field != null) { + invoker = new InvokerPair(field, new TypeDescriptor(field)); + this.readerCache.put(cacheKey, invoker); + } + } + if (field != null) { + try { + ReflectionUtils.makeAccessible(field); + Object value = field.get(target); + return new TypedValue(value, invoker.typeDescriptor.narrow(value)); + } + catch (Exception ex) { + throw new AccessException("Unable to access field: " + name, ex); + } + } + } + + throw new AccessException("Neither getter nor field found for property '" + name + "'"); + } + + public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException { + if (target == null) { + return false; + } + Class<?> type = (target instanceof Class ? (Class<?>) target : target.getClass()); + CacheKey cacheKey = new CacheKey(type, name); + if (this.writerCache.containsKey(cacheKey)) { + return true; + } + Method method = findSetterForProperty(name, type, target instanceof Class); + if (method != null) { + // Treat it like a property + Property property = new Property(type, null, method); + TypeDescriptor typeDescriptor = new TypeDescriptor(property); + this.writerCache.put(cacheKey, method); + this.typeDescriptorCache.put(cacheKey, typeDescriptor); + return true; + } + else { + Field field = findField(name, type, target instanceof Class); + if (field != null) { + this.writerCache.put(cacheKey, field); + this.typeDescriptorCache.put(cacheKey, new TypeDescriptor(field)); + return true; + } + } + return false; + } + + public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException { + if (target == null) { + throw new AccessException("Cannot write property on null target"); + } + Class<?> type = (target instanceof Class ? (Class<?>) target : target.getClass()); + + Object possiblyConvertedNewValue = newValue; + TypeDescriptor typeDescriptor = getTypeDescriptor(context, target, name); + if (typeDescriptor != null) { + try { + possiblyConvertedNewValue = context.getTypeConverter().convertValue( + newValue, TypeDescriptor.forObject(newValue), typeDescriptor); + } + catch (EvaluationException evaluationException) { + throw new AccessException("Type conversion failure",evaluationException); + } + } + CacheKey cacheKey = new CacheKey(type, name); + Member cachedMember = this.writerCache.get(cacheKey); + + if (cachedMember == null || cachedMember instanceof Method) { + Method method = (Method) cachedMember; + if (method == null) { + method = findSetterForProperty(name, type, target instanceof Class); + if (method != null) { + cachedMember = method; + this.writerCache.put(cacheKey, cachedMember); + } + } + if (method != null) { + try { + ReflectionUtils.makeAccessible(method); + method.invoke(target, possiblyConvertedNewValue); + return; + } + catch (Exception ex) { + throw new AccessException("Unable to access property '" + name + "' through setter", ex); + } + } + } + + if (cachedMember == null || cachedMember instanceof Field) { + Field field = (Field) cachedMember; + if (field == null) { + field = findField(name, type, target instanceof Class); + if (field != null) { + cachedMember = field; + this.writerCache.put(cacheKey, cachedMember); + } + } + if (field != null) { + try { + ReflectionUtils.makeAccessible(field); + field.set(target, possiblyConvertedNewValue); + return; + } + catch (Exception ex) { + throw new AccessException("Unable to access field: " + name, ex); + } + } + } + + throw new AccessException("Neither setter nor field found for property '" + name + "'"); + } + + private TypeDescriptor getTypeDescriptor(EvaluationContext context, Object target, String name) { + if (target == null) { + return null; + } + Class<?> type = (target instanceof Class ? (Class<?>) target : target.getClass()); + + if (type.isArray() && name.equals("length")) { + return TypeDescriptor.valueOf(Integer.TYPE); + } + CacheKey cacheKey = new CacheKey(type, name); + TypeDescriptor typeDescriptor = this.typeDescriptorCache.get(cacheKey); + if (typeDescriptor == null) { + // attempt to populate the cache entry + try { + if (canRead(context, target, name)) { + typeDescriptor = this.typeDescriptorCache.get(cacheKey); + } + else if (canWrite(context, target, name)) { + typeDescriptor = this.typeDescriptorCache.get(cacheKey); + } + } + catch (AccessException ex) { + // continue with null type descriptor + } + } + return typeDescriptor; + } + + /** + * Find a getter method for the specified property. A getter is defined as a method whose name start with the prefix + * 'get' and the rest of the name is the same as the property name (with the first character uppercased). + */ + protected Method findGetterForProperty(String propertyName, Class<?> clazz, boolean mustBeStatic) { + Method[] ms = clazz.getMethods(); + // Try "get*" method... + String getterName = "get" + StringUtils.capitalize(propertyName); + for (Method method : ms) { + if (method.getName().equals(getterName) && method.getParameterTypes().length == 0 && + (!mustBeStatic || Modifier.isStatic(method.getModifiers()))) { + return method; + } + } + // Try "is*" method... + getterName = "is" + StringUtils.capitalize(propertyName); + for (Method method : ms) { + if (method.getName().equals(getterName) && method.getParameterTypes().length == 0 && + boolean.class.equals(method.getReturnType()) && + (!mustBeStatic || Modifier.isStatic(method.getModifiers()))) { + return method; + } + } + return null; + } + + /** + * Find a setter method for the specified property. + */ + protected Method findSetterForProperty(String propertyName, Class<?> clazz, boolean mustBeStatic) { + Method[] methods = clazz.getMethods(); + String setterName = "set" + StringUtils.capitalize(propertyName); + for (Method method : methods) { + if (method.getName().equals(setterName) && method.getParameterTypes().length == 1 && + (!mustBeStatic || Modifier.isStatic(method.getModifiers()))) { + return method; + } + } + return null; + } + + /** + * Find a field of a certain name on a specified class + */ + protected Field findField(String name, Class<?> clazz, boolean mustBeStatic) { + Field[] fields = clazz.getFields(); + for (Field field : fields) { + if (field.getName().equals(name) && (!mustBeStatic || Modifier.isStatic(field.getModifiers()))) { + return field; + } + } + return null; + } + + /** + * Captures the member (method/field) to call reflectively to access a property value and the type descriptor for the + * value returned by the reflective call. + */ + private static class InvokerPair { + + final Member member; + + final TypeDescriptor typeDescriptor; + + public InvokerPair(Member member, TypeDescriptor typeDescriptor) { + this.member = member; + this.typeDescriptor = typeDescriptor; + } + + } + + private static class CacheKey { + + private final Class clazz; + + private final String name; + + public CacheKey(Class clazz, String name) { + this.clazz = clazz; + this.name = name; + } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof CacheKey)) { + return false; + } + CacheKey otherKey = (CacheKey) other; + return (this.clazz.equals(otherKey.clazz) && this.name.equals(otherKey.name)); + } + + @Override + public int hashCode() { + return this.clazz.hashCode() * 29 + this.name.hashCode(); + } + } + + /** + * Attempt to create an optimized property accessor tailored for a property of a particular name on + * a particular class. The general ReflectivePropertyAccessor will always work but is not optimal + * due to the need to lookup which reflective member (method/field) to use each time read() is called. + * This method will just return the ReflectivePropertyAccessor instance if it is unable to build + * something more optimal. + */ + public PropertyAccessor createOptimalAccessor(EvaluationContext eContext, Object target, String name) { + // Don't be clever for arrays or null target + if (target == null) { + return this; + } + Class<?> type = (target instanceof Class ? (Class<?>) target : target.getClass()); + if (type.isArray()) { + return this; + } + + CacheKey cacheKey = new CacheKey(type, name); + InvokerPair invocationTarget = this.readerCache.get(cacheKey); + + if (invocationTarget == null || invocationTarget.member instanceof Method) { + Method method = (Method) (invocationTarget==null?null:invocationTarget.member); + if (method == null) { + method = findGetterForProperty(name, type, target instanceof Class); + if (method != null) { + invocationTarget = new InvokerPair(method,new TypeDescriptor(new MethodParameter(method,-1))); + ReflectionUtils.makeAccessible(method); + this.readerCache.put(cacheKey, invocationTarget); + } + } + if (method != null) { + return new OptimalPropertyAccessor(invocationTarget); + } + } + + if (invocationTarget == null || invocationTarget.member instanceof Field) { + Field field = (Field) (invocationTarget==null?null:invocationTarget.member); + if (field == null) { + field = findField(name, type, target instanceof Class); + if (field != null) { + invocationTarget = new InvokerPair(field, new TypeDescriptor(field)); + ReflectionUtils.makeAccessible(field); + this.readerCache.put(cacheKey, invocationTarget); + } + } + if (field != null) { + return new OptimalPropertyAccessor(invocationTarget); + } + } + return this; + } + + /** + * An optimized form of a PropertyAccessor that will use reflection but only knows how to access a particular property + * on a particular class. This is unlike the general ReflectivePropertyResolver which manages a cache of methods/fields that + * may be invoked to access different properties on different classes. This optimal accessor exists because looking up + * the appropriate reflective object by class/name on each read is not cheap. + */ + static class OptimalPropertyAccessor implements PropertyAccessor { + private final Member member; + private final TypeDescriptor typeDescriptor; + private final boolean needsToBeMadeAccessible; + + OptimalPropertyAccessor(InvokerPair target) { + this.member = target.member; + this.typeDescriptor = target.typeDescriptor; + if (this.member instanceof Field) { + Field field = (Field)member; + needsToBeMadeAccessible = (!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers())) + && !field.isAccessible(); + } + else { + Method method = (Method)member; + needsToBeMadeAccessible = ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers())) + && !method.isAccessible()); + } + } + + public Class[] getSpecificTargetClasses() { + throw new UnsupportedOperationException("Should not be called on an OptimalPropertyAccessor"); + } + + public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException { + if (target == null) { + return false; + } + Class<?> type = (target instanceof Class ? (Class<?>) target : target.getClass()); + if (type.isArray()) { + return false; + } + if (member instanceof Method) { + Method method = (Method)member; + String getterName = "get" + StringUtils.capitalize(name); + if (getterName.equals(method.getName())) { + return true; + } + getterName = "is" + StringUtils.capitalize(name); + return getterName.equals(method.getName()); + } + else { + Field field = (Field)member; + return field.getName().equals(name); + } + } + + public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException { + if (member instanceof Method) { + try { + if (needsToBeMadeAccessible) { + ReflectionUtils.makeAccessible((Method) member); + } + Object value = ((Method) member).invoke(target); + return new TypedValue(value, typeDescriptor.narrow(value)); + } + catch (Exception ex) { + throw new AccessException("Unable to access property '" + name + "' through getter", ex); + } + } + if (member instanceof Field) { + try { + if (needsToBeMadeAccessible) { + ReflectionUtils.makeAccessible((Field)member); + } + Object value = ((Field)member).get(target); + return new TypedValue(value, typeDescriptor.narrow(value)); + } + catch (Exception ex) { + throw new AccessException("Unable to access field: " + name, ex); + } + } + throw new AccessException("Neither getter nor field found for property '" + name + "'"); + } + + public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException { + throw new UnsupportedOperationException("Should not be called on an OptimalPropertyAccessor"); + } + + public void write(EvaluationContext context, Object target, String name, Object newValue) + throws AccessException { + throw new UnsupportedOperationException("Should not be called on an OptimalPropertyAccessor"); + } + } + +} diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/StandardOperatorOverloader.java b/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/StandardOperatorOverloader.java index 0b03aa702ac..5b42d0a0105 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/StandardOperatorOverloader.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/StandardOperatorOverloader.java @@ -1,38 +1,38 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.expression.spel.support; - -import org.springframework.expression.EvaluationException; -import org.springframework.expression.Operation; -import org.springframework.expression.OperatorOverloader; - -/** - * @author Juergen Hoeller - * @since 3.0 - */ -public class StandardOperatorOverloader implements OperatorOverloader { - - public boolean overridesOperation(Operation operation, Object leftOperand, Object rightOperand) - throws EvaluationException { - return false; - } - - public Object operate(Operation operation, Object leftOperand, Object rightOperand) throws EvaluationException { - throw new EvaluationException("No operation overloaded by default"); - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.expression.spel.support; + +import org.springframework.expression.EvaluationException; +import org.springframework.expression.Operation; +import org.springframework.expression.OperatorOverloader; + +/** + * @author Juergen Hoeller + * @since 3.0 + */ +public class StandardOperatorOverloader implements OperatorOverloader { + + public boolean overridesOperation(Operation operation, Object leftOperand, Object rightOperand) + throws EvaluationException { + return false; + } + + public Object operate(Operation operation, Object leftOperand, Object rightOperand) throws EvaluationException { + throw new EvaluationException("No operation overloaded by default"); + } + +} diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/StandardTypeConverter.java b/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/StandardTypeConverter.java index 52039e35c77..49c0b3c2bdc 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/StandardTypeConverter.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/StandardTypeConverter.java @@ -1,76 +1,76 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.expression.spel.support; - -import org.springframework.core.convert.ConversionException; -import org.springframework.core.convert.ConversionService; -import org.springframework.core.convert.ConverterNotFoundException; -import org.springframework.core.convert.TypeDescriptor; -import org.springframework.core.convert.support.DefaultConversionService; -import org.springframework.expression.TypeConverter; -import org.springframework.expression.spel.SpelEvaluationException; -import org.springframework.expression.spel.SpelMessage; -import org.springframework.util.Assert; - -/** - * Default implementation of the {@link TypeConverter} interface, - * delegating to a core Spring {@link ConversionService}. - * - * @author Juergen Hoeller - * @author Andy Clement - * @since 3.0 - * @see org.springframework.core.convert.ConversionService - */ -public class StandardTypeConverter implements TypeConverter { - - private static ConversionService defaultConversionService; - - private final ConversionService conversionService; - - - public StandardTypeConverter() { - synchronized (this) { - if (defaultConversionService == null) { - defaultConversionService = new DefaultConversionService(); - } - } - this.conversionService = defaultConversionService; - } - - public StandardTypeConverter(ConversionService conversionService) { - Assert.notNull(conversionService, "ConversionService must not be null"); - this.conversionService = conversionService; - } - - - public boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType) { - return this.conversionService.canConvert(sourceType, targetType); - } - - public Object convertValue(Object value, TypeDescriptor sourceType, TypeDescriptor targetType) { - try { - return this.conversionService.convert(value, sourceType, targetType); - } - catch (ConverterNotFoundException cenfe) { - throw new SpelEvaluationException(cenfe, SpelMessage.TYPE_CONVERSION_ERROR, sourceType.toString(), targetType.toString()); - } - catch (ConversionException ce) { - throw new SpelEvaluationException(ce, SpelMessage.TYPE_CONVERSION_ERROR, sourceType.toString(), targetType.toString()); - } - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.expression.spel.support; + +import org.springframework.core.convert.ConversionException; +import org.springframework.core.convert.ConversionService; +import org.springframework.core.convert.ConverterNotFoundException; +import org.springframework.core.convert.TypeDescriptor; +import org.springframework.core.convert.support.DefaultConversionService; +import org.springframework.expression.TypeConverter; +import org.springframework.expression.spel.SpelEvaluationException; +import org.springframework.expression.spel.SpelMessage; +import org.springframework.util.Assert; + +/** + * Default implementation of the {@link TypeConverter} interface, + * delegating to a core Spring {@link ConversionService}. + * + * @author Juergen Hoeller + * @author Andy Clement + * @since 3.0 + * @see org.springframework.core.convert.ConversionService + */ +public class StandardTypeConverter implements TypeConverter { + + private static ConversionService defaultConversionService; + + private final ConversionService conversionService; + + + public StandardTypeConverter() { + synchronized (this) { + if (defaultConversionService == null) { + defaultConversionService = new DefaultConversionService(); + } + } + this.conversionService = defaultConversionService; + } + + public StandardTypeConverter(ConversionService conversionService) { + Assert.notNull(conversionService, "ConversionService must not be null"); + this.conversionService = conversionService; + } + + + public boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType) { + return this.conversionService.canConvert(sourceType, targetType); + } + + public Object convertValue(Object value, TypeDescriptor sourceType, TypeDescriptor targetType) { + try { + return this.conversionService.convert(value, sourceType, targetType); + } + catch (ConverterNotFoundException cenfe) { + throw new SpelEvaluationException(cenfe, SpelMessage.TYPE_CONVERSION_ERROR, sourceType.toString(), targetType.toString()); + } + catch (ConversionException ce) { + throw new SpelEvaluationException(ce, SpelMessage.TYPE_CONVERSION_ERROR, sourceType.toString(), targetType.toString()); + } + } + +} diff --git a/org.springframework.expression/src/test/java/org/springframework/expression/spel/SpelUtilities.java b/org.springframework.expression/src/test/java/org/springframework/expression/spel/SpelUtilities.java index 61908343284..1833cc983a0 100644 --- a/org.springframework.expression/src/test/java/org/springframework/expression/spel/SpelUtilities.java +++ b/org.springframework.expression/src/test/java/org/springframework/expression/spel/SpelUtilities.java @@ -1,58 +1,58 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.expression.spel; - -import java.io.PrintStream; - -import org.springframework.expression.Expression; -import org.springframework.expression.spel.standard.SpelExpression; - -/** - * Utilities for working with Spring Expressions. - * - * @author Andy Clement - */ -public class SpelUtilities { - - /** - * Output an indented representation of the expression syntax tree to the specified output stream. - * @param printStream the output stream to print into - * @param expression the expression to be displayed - */ - public static void printAbstractSyntaxTree(PrintStream printStream, Expression expression) { - printStream.println("===> Expression '" + expression.getExpressionString() + "' - AST start"); - printAST(printStream, ((SpelExpression) expression).getAST(), ""); - printStream.println("===> Expression '" + expression.getExpressionString() + "' - AST end"); - } - - /* - * Helper method for printing the AST with indentation - */ - private static void printAST(PrintStream out, SpelNode t, String indent) { - if (t != null) { - StringBuilder sb = new StringBuilder(); - sb.append(indent).append(t.getClass().getSimpleName()); - sb.append(" value:").append(t.toStringAST()); - sb.append(t.getChildCount() < 2 ? "" : " #children:" + t.getChildCount()); - out.println(sb.toString()); - for (int i = 0; i < t.getChildCount(); i++) { - printAST(out, t.getChild(i), indent + " "); - } - } - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.expression.spel; + +import java.io.PrintStream; + +import org.springframework.expression.Expression; +import org.springframework.expression.spel.standard.SpelExpression; + +/** + * Utilities for working with Spring Expressions. + * + * @author Andy Clement + */ +public class SpelUtilities { + + /** + * Output an indented representation of the expression syntax tree to the specified output stream. + * @param printStream the output stream to print into + * @param expression the expression to be displayed + */ + public static void printAbstractSyntaxTree(PrintStream printStream, Expression expression) { + printStream.println("===> Expression '" + expression.getExpressionString() + "' - AST start"); + printAST(printStream, ((SpelExpression) expression).getAST(), ""); + printStream.println("===> Expression '" + expression.getExpressionString() + "' - AST end"); + } + + /* + * Helper method for printing the AST with indentation + */ + private static void printAST(PrintStream out, SpelNode t, String indent) { + if (t != null) { + StringBuilder sb = new StringBuilder(); + sb.append(indent).append(t.getClass().getSimpleName()); + sb.append(" value:").append(t.toStringAST()); + sb.append(t.getChildCount() < 2 ? "" : " #children:" + t.getChildCount()); + out.println(sb.toString()); + for (int i = 0; i < t.getChildCount(); i++) { + printAST(out, t.getChild(i), indent + " "); + } + } + } + +} diff --git a/org.springframework.expression/src/test/java/org/springframework/expression/spel/ast/FormatHelperTests.java b/org.springframework.expression/src/test/java/org/springframework/expression/spel/ast/FormatHelperTests.java index abd8ed775e1..b40ec92a984 100644 --- a/org.springframework.expression/src/test/java/org/springframework/expression/spel/ast/FormatHelperTests.java +++ b/org.springframework.expression/src/test/java/org/springframework/expression/spel/ast/FormatHelperTests.java @@ -1,44 +1,44 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.expression.spel.ast; - -import java.util.Arrays; - -import org.junit.Test; - -import org.springframework.core.convert.TypeDescriptor; - -import static org.junit.Assert.*; - -/** - * @author Andy Wilkinson - */ -public class FormatHelperTests { - - @Test - public void formatMethodWithSingleArgumentForMessage() { - String message = FormatHelper.formatMethodForMessage("foo", Arrays.asList(TypeDescriptor.forObject("a string"))); - assertEquals("foo(java.lang.String)", message); - } - - @Test - public void formatMethodWithMultipleArgumentsForMessage() { - String message = FormatHelper.formatMethodForMessage("foo", Arrays.asList(TypeDescriptor.forObject("a string"), TypeDescriptor.forObject(Integer.valueOf(5)))); - assertEquals("foo(java.lang.String,java.lang.Integer)", message); - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.expression.spel.ast; + +import java.util.Arrays; + +import org.junit.Test; + +import org.springframework.core.convert.TypeDescriptor; + +import static org.junit.Assert.*; + +/** + * @author Andy Wilkinson + */ +public class FormatHelperTests { + + @Test + public void formatMethodWithSingleArgumentForMessage() { + String message = FormatHelper.formatMethodForMessage("foo", Arrays.asList(TypeDescriptor.forObject("a string"))); + assertEquals("foo(java.lang.String)", message); + } + + @Test + public void formatMethodWithMultipleArgumentsForMessage() { + String message = FormatHelper.formatMethodForMessage("foo", Arrays.asList(TypeDescriptor.forObject("a string"), TypeDescriptor.forObject(Integer.valueOf(5)))); + assertEquals("foo(java.lang.String,java.lang.Integer)", message); + } + +} diff --git a/org.springframework.expression/src/test/java/org/springframework/expression/spel/standard/PropertiesConversionSpelTests.java b/org.springframework.expression/src/test/java/org/springframework/expression/spel/standard/PropertiesConversionSpelTests.java index ebac11450ef..bf3435d55bd 100644 --- a/org.springframework.expression/src/test/java/org/springframework/expression/spel/standard/PropertiesConversionSpelTests.java +++ b/org.springframework.expression/src/test/java/org/springframework/expression/spel/standard/PropertiesConversionSpelTests.java @@ -1,106 +1,106 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.expression.spel.standard; - -import static org.junit.Assert.assertEquals; - -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; -import java.util.UUID; - -import org.junit.Test; - -import org.springframework.expression.Expression; -import org.springframework.expression.spel.standard.SpelExpressionParser; -import org.springframework.expression.spel.support.StandardEvaluationContext; - -/** - * @author Mark Fisher - */ -public class PropertiesConversionSpelTests { - - private static final SpelExpressionParser parser = new SpelExpressionParser(); - - @Test - public void props() { - Properties props = new Properties(); - props.setProperty("x", "1"); - props.setProperty("y", "2"); - props.setProperty("z", "3"); - Expression expression = parser.parseExpression("foo(#props)"); - StandardEvaluationContext context = new StandardEvaluationContext(); - context.setVariable("props", props); - String result = expression.getValue(context, new TestBean(), String.class); - assertEquals("123", result); - } - - @Test - public void mapWithAllStringValues() { - Map<String, Object> map = new HashMap<String, Object>(); - map.put("x", "1"); - map.put("y", "2"); - map.put("z", "3"); - Expression expression = parser.parseExpression("foo(#props)"); - StandardEvaluationContext context = new StandardEvaluationContext(); - context.setVariable("props", map); - String result = expression.getValue(context, new TestBean(), String.class); - assertEquals("123", result); - } - - @Test - public void mapWithNonStringValue() { - Map<String, Object> map = new HashMap<String, Object>(); - map.put("x", "1"); - map.put("y", 2); - map.put("z", "3"); - map.put("a", new UUID(1, 1)); - Expression expression = parser.parseExpression("foo(#props)"); - StandardEvaluationContext context = new StandardEvaluationContext(); - context.setVariable("props", map); - String result = expression.getValue(context, new TestBean(), String.class); - assertEquals("1null3", result); - } - - @Test - public void customMapWithNonStringValue() { - CustomMap map = new CustomMap(); - map.put("x", "1"); - map.put("y", 2); - map.put("z", "3"); - Expression expression = parser.parseExpression("foo(#props)"); - StandardEvaluationContext context = new StandardEvaluationContext(); - context.setVariable("props", map); - String result = expression.getValue(context, new TestBean(), String.class); - assertEquals("1null3", result); - } - - - private static class TestBean { - - @SuppressWarnings("unused") - public String foo(Properties props) { - return props.getProperty("x") + props.getProperty("y") + props.getProperty("z"); - } - } - - - @SuppressWarnings("serial") - private static class CustomMap extends HashMap<String, Object> { - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.expression.spel.standard; + +import static org.junit.Assert.assertEquals; + +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.UUID; + +import org.junit.Test; + +import org.springframework.expression.Expression; +import org.springframework.expression.spel.standard.SpelExpressionParser; +import org.springframework.expression.spel.support.StandardEvaluationContext; + +/** + * @author Mark Fisher + */ +public class PropertiesConversionSpelTests { + + private static final SpelExpressionParser parser = new SpelExpressionParser(); + + @Test + public void props() { + Properties props = new Properties(); + props.setProperty("x", "1"); + props.setProperty("y", "2"); + props.setProperty("z", "3"); + Expression expression = parser.parseExpression("foo(#props)"); + StandardEvaluationContext context = new StandardEvaluationContext(); + context.setVariable("props", props); + String result = expression.getValue(context, new TestBean(), String.class); + assertEquals("123", result); + } + + @Test + public void mapWithAllStringValues() { + Map<String, Object> map = new HashMap<String, Object>(); + map.put("x", "1"); + map.put("y", "2"); + map.put("z", "3"); + Expression expression = parser.parseExpression("foo(#props)"); + StandardEvaluationContext context = new StandardEvaluationContext(); + context.setVariable("props", map); + String result = expression.getValue(context, new TestBean(), String.class); + assertEquals("123", result); + } + + @Test + public void mapWithNonStringValue() { + Map<String, Object> map = new HashMap<String, Object>(); + map.put("x", "1"); + map.put("y", 2); + map.put("z", "3"); + map.put("a", new UUID(1, 1)); + Expression expression = parser.parseExpression("foo(#props)"); + StandardEvaluationContext context = new StandardEvaluationContext(); + context.setVariable("props", map); + String result = expression.getValue(context, new TestBean(), String.class); + assertEquals("1null3", result); + } + + @Test + public void customMapWithNonStringValue() { + CustomMap map = new CustomMap(); + map.put("x", "1"); + map.put("y", 2); + map.put("z", "3"); + Expression expression = parser.parseExpression("foo(#props)"); + StandardEvaluationContext context = new StandardEvaluationContext(); + context.setVariable("props", map); + String result = expression.getValue(context, new TestBean(), String.class); + assertEquals("1null3", result); + } + + + private static class TestBean { + + @SuppressWarnings("unused") + public String foo(Properties props) { + return props.getProperty("x") + props.getProperty("y") + props.getProperty("z"); + } + } + + + @SuppressWarnings("serial") + private static class CustomMap extends HashMap<String, Object> { + } + +} diff --git a/org.springframework.expression/src/test/java/org/springframework/expression/spel/standard/SpelParserTests.java b/org.springframework.expression/src/test/java/org/springframework/expression/spel/standard/SpelParserTests.java index 00ddff35f40..cc9f83883ef 100644 --- a/org.springframework.expression/src/test/java/org/springframework/expression/spel/standard/SpelParserTests.java +++ b/org.springframework.expression/src/test/java/org/springframework/expression/spel/standard/SpelParserTests.java @@ -1,370 +1,370 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.expression.spel.standard; - -import junit.framework.Assert; - -import org.junit.Test; -import org.springframework.expression.EvaluationContext; -import org.springframework.expression.EvaluationException; -import org.springframework.expression.ExpressionException; -import org.springframework.expression.ParseException; -import org.springframework.expression.spel.SpelMessage; -import org.springframework.expression.spel.SpelNode; -import org.springframework.expression.spel.SpelParseException; -import org.springframework.expression.spel.ast.OpAnd; -import org.springframework.expression.spel.ast.OpOr; -import org.springframework.expression.spel.support.StandardEvaluationContext; - -/** - * @author Andy Clement - */ -public class SpelParserTests { - - @Test - public void theMostBasic() throws EvaluationException,ParseException { - SpelExpressionParser parser = new SpelExpressionParser(); - SpelExpression expr = parser.parseRaw("2"); - Assert.assertNotNull(expr); - Assert.assertNotNull(expr.getAST()); - Assert.assertEquals(2,expr.getValue()); - Assert.assertEquals(Integer.class,expr.getValueType()); - Assert.assertEquals(2,expr.getAST().getValue(null)); - } - - @Test - public void valueType() throws Exception { - SpelExpressionParser parser = new SpelExpressionParser(); - EvaluationContext ctx = new StandardEvaluationContext(); - Class c = parser.parseRaw("2").getValueType(); - Assert.assertEquals(Integer.class,c); - c = parser.parseRaw("12").getValueType(ctx); - Assert.assertEquals(Integer.class,c); - c = parser.parseRaw("null").getValueType(); - Assert.assertNull(c); - c = parser.parseRaw("null").getValueType(ctx); - Assert.assertNull(c); - Object o = parser.parseRaw("null").getValue(ctx,Integer.class); - Assert.assertNull(o); - } - - @Test - public void whitespace() throws EvaluationException,ParseException { - SpelExpressionParser parser = new SpelExpressionParser(); - SpelExpression expr = parser.parseRaw("2 + 3"); - Assert.assertEquals(5,expr.getValue()); - expr = parser.parseRaw("2 + 3"); - Assert.assertEquals(5,expr.getValue()); - expr = parser.parseRaw("2\n+ 3"); - Assert.assertEquals(5,expr.getValue()); - expr = parser.parseRaw("2\r\n+\t3"); - Assert.assertEquals(5,expr.getValue()); - } - - @Test - public void arithmeticPlus1() throws EvaluationException,ParseException { - SpelExpressionParser parser = new SpelExpressionParser(); - SpelExpression expr = parser.parseRaw("2+2"); - Assert.assertNotNull(expr); - Assert.assertNotNull(expr.getAST()); - Assert.assertEquals(4,expr.getValue()); - } - - @Test - public void arithmeticPlus2() throws EvaluationException,ParseException { - SpelExpressionParser parser = new SpelExpressionParser(); - SpelExpression expr = parser.parseRaw("37+41"); - Assert.assertEquals(78,expr.getValue()); - } - - @Test - public void arithmeticMultiply1() throws EvaluationException,ParseException { - SpelExpressionParser parser = new SpelExpressionParser(); - SpelExpression expr = parser.parseRaw("2*3"); - Assert.assertNotNull(expr); - Assert.assertNotNull(expr.getAST()); -// printAst(expr.getAST(),0); - Assert.assertEquals(6,expr.getValue()); - } - - @Test - public void arithmeticPrecedence1() throws EvaluationException,ParseException { - SpelExpressionParser parser = new SpelExpressionParser(); - SpelExpression expr = parser.parseRaw("2*3+5"); - Assert.assertEquals(11,expr.getValue()); - } - - @Test - public void generalExpressions() throws Exception { - try { - SpelExpressionParser parser = new SpelExpressionParser(); - parser.parseRaw("new String"); - Assert.fail(); - } catch (ParseException e) { - Assert.assertTrue(e instanceof SpelParseException); - SpelParseException spe = (SpelParseException)e; - Assert.assertEquals(SpelMessage.MISSING_CONSTRUCTOR_ARGS,spe.getMessageCode()); - Assert.assertEquals(10,spe.getPosition()); - } - try { - SpelExpressionParser parser = new SpelExpressionParser(); - parser.parseRaw("new String(3,"); - Assert.fail(); - } catch (ParseException e) { - Assert.assertTrue(e instanceof SpelParseException); - SpelParseException spe = (SpelParseException)e; - Assert.assertEquals(SpelMessage.RUN_OUT_OF_ARGUMENTS,spe.getMessageCode()); - Assert.assertEquals(10,spe.getPosition()); - } - try { - SpelExpressionParser parser = new SpelExpressionParser(); - parser.parseRaw("new String(3"); - Assert.fail(); - } catch (ParseException e) { - Assert.assertTrue(e instanceof SpelParseException); - SpelParseException spe = (SpelParseException)e; - Assert.assertEquals(SpelMessage.RUN_OUT_OF_ARGUMENTS,spe.getMessageCode()); - Assert.assertEquals(10,spe.getPosition()); - } - try { - SpelExpressionParser parser = new SpelExpressionParser(); - parser.parseRaw("new String("); - Assert.fail(); - } catch (ParseException e) { - Assert.assertTrue(e instanceof SpelParseException); - SpelParseException spe = (SpelParseException)e; - Assert.assertEquals(SpelMessage.RUN_OUT_OF_ARGUMENTS,spe.getMessageCode()); - Assert.assertEquals(10,spe.getPosition()); - } - try { - SpelExpressionParser parser = new SpelExpressionParser(); - parser.parseRaw("\"abc"); - Assert.fail(); - } catch (ParseException e) { - Assert.assertTrue(e instanceof SpelParseException); - SpelParseException spe = (SpelParseException)e; - Assert.assertEquals(SpelMessage.NON_TERMINATING_DOUBLE_QUOTED_STRING,spe.getMessageCode()); - Assert.assertEquals(0,spe.getPosition()); - } - try { - SpelExpressionParser parser = new SpelExpressionParser(); - parser.parseRaw("'abc"); - Assert.fail(); - } catch (ParseException e) { - Assert.assertTrue(e instanceof SpelParseException); - SpelParseException spe = (SpelParseException)e; - Assert.assertEquals(SpelMessage.NON_TERMINATING_QUOTED_STRING,spe.getMessageCode()); - Assert.assertEquals(0,spe.getPosition()); - } - - } - - @Test - public void arithmeticPrecedence2() throws EvaluationException,ParseException { - SpelExpressionParser parser = new SpelExpressionParser(); - SpelExpression expr = parser.parseRaw("2+3*5"); - Assert.assertEquals(17,expr.getValue()); - } - - @Test - public void arithmeticPrecedence3() throws EvaluationException,ParseException { - SpelExpression expr = new SpelExpressionParser().parseRaw("3+10/2"); - Assert.assertEquals(8,expr.getValue()); - } - - @Test - public void arithmeticPrecedence4() throws EvaluationException,ParseException { - SpelExpression expr = new SpelExpressionParser().parseRaw("10/2+3"); - Assert.assertEquals(8,expr.getValue()); - } - - @Test - public void arithmeticPrecedence5() throws EvaluationException,ParseException { - SpelExpression expr = new SpelExpressionParser().parseRaw("(4+10)/2"); - Assert.assertEquals(7,expr.getValue()); - } - - @Test - public void arithmeticPrecedence6() throws EvaluationException,ParseException { - SpelExpression expr = new SpelExpressionParser().parseRaw("(3+2)*2"); - Assert.assertEquals(10,expr.getValue()); - } - - @Test - public void booleanOperators() throws EvaluationException,ParseException { - SpelExpression expr = new SpelExpressionParser().parseRaw("true"); - Assert.assertEquals(Boolean.TRUE,expr.getValue(Boolean.class)); - expr = new SpelExpressionParser().parseRaw("false"); - Assert.assertEquals(Boolean.FALSE,expr.getValue(Boolean.class)); - expr = new SpelExpressionParser().parseRaw("false and false"); - Assert.assertEquals(Boolean.FALSE,expr.getValue(Boolean.class)); - expr = new SpelExpressionParser().parseRaw("true and (true or false)"); - Assert.assertEquals(Boolean.TRUE,expr.getValue(Boolean.class)); - expr = new SpelExpressionParser().parseRaw("true and true or false"); - Assert.assertEquals(Boolean.TRUE,expr.getValue(Boolean.class)); - expr = new SpelExpressionParser().parseRaw("!true"); - Assert.assertEquals(Boolean.FALSE,expr.getValue(Boolean.class)); - expr = new SpelExpressionParser().parseRaw("!(false or true)"); - Assert.assertEquals(Boolean.FALSE,expr.getValue(Boolean.class)); - } - - @Test - public void testStringLiterals() throws EvaluationException,ParseException { - SpelExpression expr = new SpelExpressionParser().parseRaw("'howdy'"); - Assert.assertEquals("howdy",expr.getValue()); - expr = new SpelExpressionParser().parseRaw("'hello '' world'"); - Assert.assertEquals("hello ' world",expr.getValue()); - } - - @Test - public void testStringLiterals2() throws EvaluationException,ParseException { - SpelExpression expr = new SpelExpressionParser().parseRaw("'howdy'.substring(0,2)"); - Assert.assertEquals("ho",expr.getValue()); - } - - @Test - public void testPositionalInformation() throws EvaluationException, ParseException { - SpelExpression expr = new SpelExpressionParser().parseRaw("true and true or false"); - SpelNode rootAst = expr.getAST(); - OpOr operatorOr = (OpOr)rootAst; - OpAnd operatorAnd = (OpAnd)operatorOr.getLeftOperand(); - SpelNode rightOrOperand = operatorOr.getRightOperand(); - - // check position for final 'false' - Assert.assertEquals(17, rightOrOperand.getStartPosition()); - Assert.assertEquals(22, rightOrOperand.getEndPosition()); - - // check position for first 'true' - Assert.assertEquals(0, operatorAnd.getLeftOperand().getStartPosition()); - Assert.assertEquals(4, operatorAnd.getLeftOperand().getEndPosition()); - - // check position for second 'true' - Assert.assertEquals(9, operatorAnd.getRightOperand().getStartPosition()); - Assert.assertEquals(13, operatorAnd.getRightOperand().getEndPosition()); - - // check position for OperatorAnd - Assert.assertEquals(5, operatorAnd.getStartPosition()); - Assert.assertEquals(8, operatorAnd.getEndPosition()); - - // check position for OperatorOr - Assert.assertEquals(14, operatorOr.getStartPosition()); - Assert.assertEquals(16, operatorOr.getEndPosition()); - } - - @Test - public void testTokenKind() { - TokenKind tk = TokenKind.NOT; - Assert.assertFalse(tk.hasPayload()); - Assert.assertEquals("NOT(!)",tk.toString()); - - tk = TokenKind.MINUS; - Assert.assertFalse(tk.hasPayload()); - Assert.assertEquals("MINUS(-)",tk.toString()); - - tk = TokenKind.LITERAL_STRING; - Assert.assertEquals("LITERAL_STRING",tk.toString()); - Assert.assertTrue(tk.hasPayload()); - } - - @Test - public void testToken() { - Token token = new Token(TokenKind.NOT,0,3); - Assert.assertEquals(TokenKind.NOT,token.kind); - Assert.assertEquals(0,token.startpos); - Assert.assertEquals(3,token.endpos); - Assert.assertEquals("[NOT(!)](0,3)",token.toString()); - - token = new Token(TokenKind.LITERAL_STRING,"abc".toCharArray(),0,3); - Assert.assertEquals(TokenKind.LITERAL_STRING,token.kind); - Assert.assertEquals(0,token.startpos); - Assert.assertEquals(3,token.endpos); - Assert.assertEquals("[LITERAL_STRING:abc](0,3)",token.toString()); - } - - @Test - public void testExceptions() { - ExpressionException exprEx = new ExpressionException("test"); - Assert.assertEquals("test", exprEx.getMessage()); - Assert.assertEquals("test", exprEx.toDetailedString()); - - exprEx = new ExpressionException("wibble","test"); - Assert.assertEquals("test", exprEx.getMessage()); - Assert.assertEquals("Expression 'wibble': test", exprEx.toDetailedString()); - - exprEx = new ExpressionException("wibble",3, "test"); - Assert.assertEquals("test", exprEx.getMessage()); - Assert.assertEquals("Expression 'wibble' @ 3: test", exprEx.toDetailedString()); - } - - @Test - public void testNumerics() { - checkNumber("2",2,Integer.class); - checkNumber("22",22,Integer.class); - checkNumber("+22",22,Integer.class); - checkNumber("-22",-22,Integer.class); - - checkNumber("2L",2L,Long.class); - checkNumber("22l",22L,Long.class); - - checkNumber("0x1",1,Integer.class); - checkNumber("0x1L",1L,Long.class); - checkNumber("0xa",10,Integer.class); - checkNumber("0xAL",10L,Long.class); - - checkNumberError("0x",SpelMessage.NOT_AN_INTEGER); - checkNumberError("0xL",SpelMessage.NOT_A_LONG); - - checkNumberError(".324",SpelMessage.UNEXPECTED_DATA_AFTER_DOT); - - checkNumberError("3.4L",SpelMessage.REAL_CANNOT_BE_LONG); - - // Number is parsed as a float, but immediately promoted to a double - checkNumber("3.5f",3.5d,Double.class); - - checkNumber("1.2e3", 1.2e3d, Double.class); - checkNumber("1.2e+3", 1.2e3d, Double.class); - checkNumber("1.2e-3", 1.2e-3d, Double.class); - checkNumber("1.2e3", 1.2e3d, Double.class); - checkNumber("1.e+3", 1.e3d, Double.class); - checkNumber("1e+3", 1e3d, Double.class); - } - - private void checkNumber(String expression, Object value, Class<?> type) { - try { - SpelExpressionParser parser = new SpelExpressionParser(); - SpelExpression expr = parser.parseRaw(expression); - Object o = expr.getValue(); - Assert.assertEquals(value,o); - Assert.assertEquals(type,o.getClass()); - } catch (Exception e) { - e.printStackTrace(); - Assert.fail(e.getMessage()); - } - } - - private void checkNumberError(String expression, SpelMessage expectedMessage) { - try { - SpelExpressionParser parser = new SpelExpressionParser(); - parser.parseRaw(expression); - Assert.fail(); - } catch (ParseException e) { - Assert.assertTrue(e instanceof SpelParseException); - SpelParseException spe = (SpelParseException)e; - Assert.assertEquals(expectedMessage,spe.getMessageCode()); - } - } -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.expression.spel.standard; + +import junit.framework.Assert; + +import org.junit.Test; +import org.springframework.expression.EvaluationContext; +import org.springframework.expression.EvaluationException; +import org.springframework.expression.ExpressionException; +import org.springframework.expression.ParseException; +import org.springframework.expression.spel.SpelMessage; +import org.springframework.expression.spel.SpelNode; +import org.springframework.expression.spel.SpelParseException; +import org.springframework.expression.spel.ast.OpAnd; +import org.springframework.expression.spel.ast.OpOr; +import org.springframework.expression.spel.support.StandardEvaluationContext; + +/** + * @author Andy Clement + */ +public class SpelParserTests { + + @Test + public void theMostBasic() throws EvaluationException,ParseException { + SpelExpressionParser parser = new SpelExpressionParser(); + SpelExpression expr = parser.parseRaw("2"); + Assert.assertNotNull(expr); + Assert.assertNotNull(expr.getAST()); + Assert.assertEquals(2,expr.getValue()); + Assert.assertEquals(Integer.class,expr.getValueType()); + Assert.assertEquals(2,expr.getAST().getValue(null)); + } + + @Test + public void valueType() throws Exception { + SpelExpressionParser parser = new SpelExpressionParser(); + EvaluationContext ctx = new StandardEvaluationContext(); + Class c = parser.parseRaw("2").getValueType(); + Assert.assertEquals(Integer.class,c); + c = parser.parseRaw("12").getValueType(ctx); + Assert.assertEquals(Integer.class,c); + c = parser.parseRaw("null").getValueType(); + Assert.assertNull(c); + c = parser.parseRaw("null").getValueType(ctx); + Assert.assertNull(c); + Object o = parser.parseRaw("null").getValue(ctx,Integer.class); + Assert.assertNull(o); + } + + @Test + public void whitespace() throws EvaluationException,ParseException { + SpelExpressionParser parser = new SpelExpressionParser(); + SpelExpression expr = parser.parseRaw("2 + 3"); + Assert.assertEquals(5,expr.getValue()); + expr = parser.parseRaw("2 + 3"); + Assert.assertEquals(5,expr.getValue()); + expr = parser.parseRaw("2\n+ 3"); + Assert.assertEquals(5,expr.getValue()); + expr = parser.parseRaw("2\r\n+\t3"); + Assert.assertEquals(5,expr.getValue()); + } + + @Test + public void arithmeticPlus1() throws EvaluationException,ParseException { + SpelExpressionParser parser = new SpelExpressionParser(); + SpelExpression expr = parser.parseRaw("2+2"); + Assert.assertNotNull(expr); + Assert.assertNotNull(expr.getAST()); + Assert.assertEquals(4,expr.getValue()); + } + + @Test + public void arithmeticPlus2() throws EvaluationException,ParseException { + SpelExpressionParser parser = new SpelExpressionParser(); + SpelExpression expr = parser.parseRaw("37+41"); + Assert.assertEquals(78,expr.getValue()); + } + + @Test + public void arithmeticMultiply1() throws EvaluationException,ParseException { + SpelExpressionParser parser = new SpelExpressionParser(); + SpelExpression expr = parser.parseRaw("2*3"); + Assert.assertNotNull(expr); + Assert.assertNotNull(expr.getAST()); +// printAst(expr.getAST(),0); + Assert.assertEquals(6,expr.getValue()); + } + + @Test + public void arithmeticPrecedence1() throws EvaluationException,ParseException { + SpelExpressionParser parser = new SpelExpressionParser(); + SpelExpression expr = parser.parseRaw("2*3+5"); + Assert.assertEquals(11,expr.getValue()); + } + + @Test + public void generalExpressions() throws Exception { + try { + SpelExpressionParser parser = new SpelExpressionParser(); + parser.parseRaw("new String"); + Assert.fail(); + } catch (ParseException e) { + Assert.assertTrue(e instanceof SpelParseException); + SpelParseException spe = (SpelParseException)e; + Assert.assertEquals(SpelMessage.MISSING_CONSTRUCTOR_ARGS,spe.getMessageCode()); + Assert.assertEquals(10,spe.getPosition()); + } + try { + SpelExpressionParser parser = new SpelExpressionParser(); + parser.parseRaw("new String(3,"); + Assert.fail(); + } catch (ParseException e) { + Assert.assertTrue(e instanceof SpelParseException); + SpelParseException spe = (SpelParseException)e; + Assert.assertEquals(SpelMessage.RUN_OUT_OF_ARGUMENTS,spe.getMessageCode()); + Assert.assertEquals(10,spe.getPosition()); + } + try { + SpelExpressionParser parser = new SpelExpressionParser(); + parser.parseRaw("new String(3"); + Assert.fail(); + } catch (ParseException e) { + Assert.assertTrue(e instanceof SpelParseException); + SpelParseException spe = (SpelParseException)e; + Assert.assertEquals(SpelMessage.RUN_OUT_OF_ARGUMENTS,spe.getMessageCode()); + Assert.assertEquals(10,spe.getPosition()); + } + try { + SpelExpressionParser parser = new SpelExpressionParser(); + parser.parseRaw("new String("); + Assert.fail(); + } catch (ParseException e) { + Assert.assertTrue(e instanceof SpelParseException); + SpelParseException spe = (SpelParseException)e; + Assert.assertEquals(SpelMessage.RUN_OUT_OF_ARGUMENTS,spe.getMessageCode()); + Assert.assertEquals(10,spe.getPosition()); + } + try { + SpelExpressionParser parser = new SpelExpressionParser(); + parser.parseRaw("\"abc"); + Assert.fail(); + } catch (ParseException e) { + Assert.assertTrue(e instanceof SpelParseException); + SpelParseException spe = (SpelParseException)e; + Assert.assertEquals(SpelMessage.NON_TERMINATING_DOUBLE_QUOTED_STRING,spe.getMessageCode()); + Assert.assertEquals(0,spe.getPosition()); + } + try { + SpelExpressionParser parser = new SpelExpressionParser(); + parser.parseRaw("'abc"); + Assert.fail(); + } catch (ParseException e) { + Assert.assertTrue(e instanceof SpelParseException); + SpelParseException spe = (SpelParseException)e; + Assert.assertEquals(SpelMessage.NON_TERMINATING_QUOTED_STRING,spe.getMessageCode()); + Assert.assertEquals(0,spe.getPosition()); + } + + } + + @Test + public void arithmeticPrecedence2() throws EvaluationException,ParseException { + SpelExpressionParser parser = new SpelExpressionParser(); + SpelExpression expr = parser.parseRaw("2+3*5"); + Assert.assertEquals(17,expr.getValue()); + } + + @Test + public void arithmeticPrecedence3() throws EvaluationException,ParseException { + SpelExpression expr = new SpelExpressionParser().parseRaw("3+10/2"); + Assert.assertEquals(8,expr.getValue()); + } + + @Test + public void arithmeticPrecedence4() throws EvaluationException,ParseException { + SpelExpression expr = new SpelExpressionParser().parseRaw("10/2+3"); + Assert.assertEquals(8,expr.getValue()); + } + + @Test + public void arithmeticPrecedence5() throws EvaluationException,ParseException { + SpelExpression expr = new SpelExpressionParser().parseRaw("(4+10)/2"); + Assert.assertEquals(7,expr.getValue()); + } + + @Test + public void arithmeticPrecedence6() throws EvaluationException,ParseException { + SpelExpression expr = new SpelExpressionParser().parseRaw("(3+2)*2"); + Assert.assertEquals(10,expr.getValue()); + } + + @Test + public void booleanOperators() throws EvaluationException,ParseException { + SpelExpression expr = new SpelExpressionParser().parseRaw("true"); + Assert.assertEquals(Boolean.TRUE,expr.getValue(Boolean.class)); + expr = new SpelExpressionParser().parseRaw("false"); + Assert.assertEquals(Boolean.FALSE,expr.getValue(Boolean.class)); + expr = new SpelExpressionParser().parseRaw("false and false"); + Assert.assertEquals(Boolean.FALSE,expr.getValue(Boolean.class)); + expr = new SpelExpressionParser().parseRaw("true and (true or false)"); + Assert.assertEquals(Boolean.TRUE,expr.getValue(Boolean.class)); + expr = new SpelExpressionParser().parseRaw("true and true or false"); + Assert.assertEquals(Boolean.TRUE,expr.getValue(Boolean.class)); + expr = new SpelExpressionParser().parseRaw("!true"); + Assert.assertEquals(Boolean.FALSE,expr.getValue(Boolean.class)); + expr = new SpelExpressionParser().parseRaw("!(false or true)"); + Assert.assertEquals(Boolean.FALSE,expr.getValue(Boolean.class)); + } + + @Test + public void testStringLiterals() throws EvaluationException,ParseException { + SpelExpression expr = new SpelExpressionParser().parseRaw("'howdy'"); + Assert.assertEquals("howdy",expr.getValue()); + expr = new SpelExpressionParser().parseRaw("'hello '' world'"); + Assert.assertEquals("hello ' world",expr.getValue()); + } + + @Test + public void testStringLiterals2() throws EvaluationException,ParseException { + SpelExpression expr = new SpelExpressionParser().parseRaw("'howdy'.substring(0,2)"); + Assert.assertEquals("ho",expr.getValue()); + } + + @Test + public void testPositionalInformation() throws EvaluationException, ParseException { + SpelExpression expr = new SpelExpressionParser().parseRaw("true and true or false"); + SpelNode rootAst = expr.getAST(); + OpOr operatorOr = (OpOr)rootAst; + OpAnd operatorAnd = (OpAnd)operatorOr.getLeftOperand(); + SpelNode rightOrOperand = operatorOr.getRightOperand(); + + // check position for final 'false' + Assert.assertEquals(17, rightOrOperand.getStartPosition()); + Assert.assertEquals(22, rightOrOperand.getEndPosition()); + + // check position for first 'true' + Assert.assertEquals(0, operatorAnd.getLeftOperand().getStartPosition()); + Assert.assertEquals(4, operatorAnd.getLeftOperand().getEndPosition()); + + // check position for second 'true' + Assert.assertEquals(9, operatorAnd.getRightOperand().getStartPosition()); + Assert.assertEquals(13, operatorAnd.getRightOperand().getEndPosition()); + + // check position for OperatorAnd + Assert.assertEquals(5, operatorAnd.getStartPosition()); + Assert.assertEquals(8, operatorAnd.getEndPosition()); + + // check position for OperatorOr + Assert.assertEquals(14, operatorOr.getStartPosition()); + Assert.assertEquals(16, operatorOr.getEndPosition()); + } + + @Test + public void testTokenKind() { + TokenKind tk = TokenKind.NOT; + Assert.assertFalse(tk.hasPayload()); + Assert.assertEquals("NOT(!)",tk.toString()); + + tk = TokenKind.MINUS; + Assert.assertFalse(tk.hasPayload()); + Assert.assertEquals("MINUS(-)",tk.toString()); + + tk = TokenKind.LITERAL_STRING; + Assert.assertEquals("LITERAL_STRING",tk.toString()); + Assert.assertTrue(tk.hasPayload()); + } + + @Test + public void testToken() { + Token token = new Token(TokenKind.NOT,0,3); + Assert.assertEquals(TokenKind.NOT,token.kind); + Assert.assertEquals(0,token.startpos); + Assert.assertEquals(3,token.endpos); + Assert.assertEquals("[NOT(!)](0,3)",token.toString()); + + token = new Token(TokenKind.LITERAL_STRING,"abc".toCharArray(),0,3); + Assert.assertEquals(TokenKind.LITERAL_STRING,token.kind); + Assert.assertEquals(0,token.startpos); + Assert.assertEquals(3,token.endpos); + Assert.assertEquals("[LITERAL_STRING:abc](0,3)",token.toString()); + } + + @Test + public void testExceptions() { + ExpressionException exprEx = new ExpressionException("test"); + Assert.assertEquals("test", exprEx.getMessage()); + Assert.assertEquals("test", exprEx.toDetailedString()); + + exprEx = new ExpressionException("wibble","test"); + Assert.assertEquals("test", exprEx.getMessage()); + Assert.assertEquals("Expression 'wibble': test", exprEx.toDetailedString()); + + exprEx = new ExpressionException("wibble",3, "test"); + Assert.assertEquals("test", exprEx.getMessage()); + Assert.assertEquals("Expression 'wibble' @ 3: test", exprEx.toDetailedString()); + } + + @Test + public void testNumerics() { + checkNumber("2",2,Integer.class); + checkNumber("22",22,Integer.class); + checkNumber("+22",22,Integer.class); + checkNumber("-22",-22,Integer.class); + + checkNumber("2L",2L,Long.class); + checkNumber("22l",22L,Long.class); + + checkNumber("0x1",1,Integer.class); + checkNumber("0x1L",1L,Long.class); + checkNumber("0xa",10,Integer.class); + checkNumber("0xAL",10L,Long.class); + + checkNumberError("0x",SpelMessage.NOT_AN_INTEGER); + checkNumberError("0xL",SpelMessage.NOT_A_LONG); + + checkNumberError(".324",SpelMessage.UNEXPECTED_DATA_AFTER_DOT); + + checkNumberError("3.4L",SpelMessage.REAL_CANNOT_BE_LONG); + + // Number is parsed as a float, but immediately promoted to a double + checkNumber("3.5f",3.5d,Double.class); + + checkNumber("1.2e3", 1.2e3d, Double.class); + checkNumber("1.2e+3", 1.2e3d, Double.class); + checkNumber("1.2e-3", 1.2e-3d, Double.class); + checkNumber("1.2e3", 1.2e3d, Double.class); + checkNumber("1.e+3", 1.e3d, Double.class); + checkNumber("1e+3", 1e3d, Double.class); + } + + private void checkNumber(String expression, Object value, Class<?> type) { + try { + SpelExpressionParser parser = new SpelExpressionParser(); + SpelExpression expr = parser.parseRaw(expression); + Object o = expr.getValue(); + Assert.assertEquals(value,o); + Assert.assertEquals(type,o.getClass()); + } catch (Exception e) { + e.printStackTrace(); + Assert.fail(e.getMessage()); + } + } + + private void checkNumberError(String expression, SpelMessage expectedMessage) { + try { + SpelExpressionParser parser = new SpelExpressionParser(); + parser.parseRaw(expression); + Assert.fail(); + } catch (ParseException e) { + Assert.assertTrue(e instanceof SpelParseException); + SpelParseException spe = (SpelParseException)e; + Assert.assertEquals(expectedMessage,spe.getMessageCode()); + } + } +} diff --git a/org.springframework.expression/src/test/java/org/springframework/expression/spel/support/StandardComponentsTests.java b/org.springframework.expression/src/test/java/org/springframework/expression/spel/support/StandardComponentsTests.java index 89d80142108..47c49ba0268 100644 --- a/org.springframework.expression/src/test/java/org/springframework/expression/spel/support/StandardComponentsTests.java +++ b/org.springframework.expression/src/test/java/org/springframework/expression/spel/support/StandardComponentsTests.java @@ -1,79 +1,79 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.expression.spel.support; - -import java.util.List; - -import org.junit.Assert; -import org.junit.Test; -import org.springframework.core.convert.TypeDescriptor; -import org.springframework.expression.EvaluationException; -import org.springframework.expression.Operation; -import org.springframework.expression.OperatorOverloader; -import org.springframework.expression.TypeComparator; -import org.springframework.expression.TypeConverter; -import org.springframework.expression.TypeLocator; - -public class StandardComponentsTests { - - @Test - public void testStandardEvaluationContext() { - StandardEvaluationContext context = new StandardEvaluationContext(); - Assert.assertNotNull(context.getTypeComparator()); - - TypeComparator tc = new StandardTypeComparator(); - context.setTypeComparator(tc); - Assert.assertEquals(tc,context.getTypeComparator()); - - TypeLocator tl = new StandardTypeLocator(); - context.setTypeLocator(tl); - Assert.assertEquals(tl,context.getTypeLocator()); - } - - @Test - public void testStandardOperatorOverloader() throws EvaluationException { - OperatorOverloader oo = new StandardOperatorOverloader(); - Assert.assertFalse(oo.overridesOperation(Operation.ADD, null, null)); - try { - oo.operate(Operation.ADD, 2, 3); - Assert.fail("should have failed"); - } catch (EvaluationException e) { - // success - } - } - - @Test - public void testStandardTypeLocator() { - StandardTypeLocator tl = new StandardTypeLocator(); - List<String> prefixes = tl.getImportPrefixes(); - Assert.assertEquals(1,prefixes.size()); - tl.registerImport("java.util"); - prefixes = tl.getImportPrefixes(); - Assert.assertEquals(2,prefixes.size()); - tl.removeImport("java.util"); - prefixes = tl.getImportPrefixes(); - Assert.assertEquals(1,prefixes.size()); - } - - @Test - public void testStandardTypeConverter() throws EvaluationException { - TypeConverter tc = new StandardTypeConverter(); - tc.convertValue(3, TypeDescriptor.forObject(3), TypeDescriptor.valueOf(Double.class)); - } - -} - +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.expression.spel.support; + +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; +import org.springframework.core.convert.TypeDescriptor; +import org.springframework.expression.EvaluationException; +import org.springframework.expression.Operation; +import org.springframework.expression.OperatorOverloader; +import org.springframework.expression.TypeComparator; +import org.springframework.expression.TypeConverter; +import org.springframework.expression.TypeLocator; + +public class StandardComponentsTests { + + @Test + public void testStandardEvaluationContext() { + StandardEvaluationContext context = new StandardEvaluationContext(); + Assert.assertNotNull(context.getTypeComparator()); + + TypeComparator tc = new StandardTypeComparator(); + context.setTypeComparator(tc); + Assert.assertEquals(tc,context.getTypeComparator()); + + TypeLocator tl = new StandardTypeLocator(); + context.setTypeLocator(tl); + Assert.assertEquals(tl,context.getTypeLocator()); + } + + @Test + public void testStandardOperatorOverloader() throws EvaluationException { + OperatorOverloader oo = new StandardOperatorOverloader(); + Assert.assertFalse(oo.overridesOperation(Operation.ADD, null, null)); + try { + oo.operate(Operation.ADD, 2, 3); + Assert.fail("should have failed"); + } catch (EvaluationException e) { + // success + } + } + + @Test + public void testStandardTypeLocator() { + StandardTypeLocator tl = new StandardTypeLocator(); + List<String> prefixes = tl.getImportPrefixes(); + Assert.assertEquals(1,prefixes.size()); + tl.registerImport("java.util"); + prefixes = tl.getImportPrefixes(); + Assert.assertEquals(2,prefixes.size()); + tl.removeImport("java.util"); + prefixes = tl.getImportPrefixes(); + Assert.assertEquals(1,prefixes.size()); + } + + @Test + public void testStandardTypeConverter() throws EvaluationException { + TypeConverter tc = new StandardTypeConverter(); + tc.convertValue(3, TypeDescriptor.forObject(3), TypeDescriptor.valueOf(Double.class)); + } + +} + diff --git a/org.springframework.expression/src/test/java/org/springframework/expression/spel/testresources/TestAddress.java b/org.springframework.expression/src/test/java/org/springframework/expression/spel/testresources/TestAddress.java index 069a42958f3..0f84c9e85ea 100644 --- a/org.springframework.expression/src/test/java/org/springframework/expression/spel/testresources/TestAddress.java +++ b/org.springframework.expression/src/test/java/org/springframework/expression/spel/testresources/TestAddress.java @@ -1,21 +1,21 @@ -package org.springframework.expression.spel.testresources; - -import java.util.List; - -public class TestAddress{ - private String street; - private List<String> crossStreets; - - public String getStreet() { - return street; - } - public void setStreet(String street) { - this.street = street; - } - public List<String> getCrossStreets() { - return crossStreets; - } - public void setCrossStreets(List<String> crossStreets) { - this.crossStreets = crossStreets; - } - } +package org.springframework.expression.spel.testresources; + +import java.util.List; + +public class TestAddress{ + private String street; + private List<String> crossStreets; + + public String getStreet() { + return street; + } + public void setStreet(String street) { + this.street = street; + } + public List<String> getCrossStreets() { + return crossStreets; + } + public void setCrossStreets(List<String> crossStreets) { + this.crossStreets = crossStreets; + } + } diff --git a/org.springframework.expression/src/test/java/org/springframework/expression/spel/testresources/TestPerson.java b/org.springframework.expression/src/test/java/org/springframework/expression/spel/testresources/TestPerson.java index 94acb313808..dca009da128 100644 --- a/org.springframework.expression/src/test/java/org/springframework/expression/spel/testresources/TestPerson.java +++ b/org.springframework.expression/src/test/java/org/springframework/expression/spel/testresources/TestPerson.java @@ -1,19 +1,19 @@ -package org.springframework.expression.spel.testresources; - -public class TestPerson { - private String name; - private TestAddress address; - - public String getName() { - return name; - } - public void setName(String name) { - this.name = name; - } - public TestAddress getAddress() { - return address; - } - public void setAddress(TestAddress address) { - this.address = address; - } +package org.springframework.expression.spel.testresources; + +public class TestPerson { + private String name; + private TestAddress address; + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public TestAddress getAddress() { + return address; + } + public void setAddress(TestAddress address) { + this.address = address; + } } \ No newline at end of file diff --git a/org.springframework.integration-tests/src/test/java/test/util/SerializationTestUtils.java b/org.springframework.integration-tests/src/test/java/test/util/SerializationTestUtils.java index 609ae77e00a..15ef78a8648 100644 --- a/org.springframework.integration-tests/src/test/java/test/util/SerializationTestUtils.java +++ b/org.springframework.integration-tests/src/test/java/test/util/SerializationTestUtils.java @@ -1,100 +1,100 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package test.util; - -import java.awt.*; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.NotSerializableException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.OutputStream; -import java.io.Serializable; - -import static org.junit.Assert.*; -import org.junit.Test; -import test.beans.TestBean; - -/** - * Utilities for testing serializability of objects. - * Exposes static methods for use in other test cases. - * Contains {@link org.junit.Test} methods to test itself. - * - * @author Rod Johnson - * @author Chris Beams - */ -public final class SerializationTestUtils { - - public static void testSerialization(Object o) throws IOException { - OutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream oos = new ObjectOutputStream(baos); - oos.writeObject(o); - } - - public static boolean isSerializable(Object o) throws IOException { - try { - testSerialization(o); - return true; - } - catch (NotSerializableException ex) { - return false; - } - } - - public static Object serializeAndDeserialize(Object o) throws IOException, ClassNotFoundException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream oos = new ObjectOutputStream(baos); - oos.writeObject(o); - oos.flush(); - baos.flush(); - byte[] bytes = baos.toByteArray(); - - ByteArrayInputStream is = new ByteArrayInputStream(bytes); - ObjectInputStream ois = new ObjectInputStream(is); - Object o2 = ois.readObject(); - return o2; - } - - - @Test(expected=NotSerializableException.class) - public void testWithNonSerializableObject() throws IOException { - TestBean o = new TestBean(); - assertFalse(o instanceof Serializable); - assertFalse(isSerializable(o)); - - testSerialization(o); - } - - @Test - public void testWithSerializableObject() throws Exception { - int x = 5; - int y = 10; - Point p = new Point(x, y); - assertTrue(p instanceof Serializable); - - testSerialization(p); - - assertTrue(isSerializable(p)); - - Point p2 = (Point) serializeAndDeserialize(p); - assertNotSame(p, p2); - assertEquals(x, (int) p2.getX()); - assertEquals(y, (int) p2.getY()); - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package test.util; + +import java.awt.*; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.NotSerializableException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.io.Serializable; + +import static org.junit.Assert.*; +import org.junit.Test; +import test.beans.TestBean; + +/** + * Utilities for testing serializability of objects. + * Exposes static methods for use in other test cases. + * Contains {@link org.junit.Test} methods to test itself. + * + * @author Rod Johnson + * @author Chris Beams + */ +public final class SerializationTestUtils { + + public static void testSerialization(Object o) throws IOException { + OutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(o); + } + + public static boolean isSerializable(Object o) throws IOException { + try { + testSerialization(o); + return true; + } + catch (NotSerializableException ex) { + return false; + } + } + + public static Object serializeAndDeserialize(Object o) throws IOException, ClassNotFoundException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(o); + oos.flush(); + baos.flush(); + byte[] bytes = baos.toByteArray(); + + ByteArrayInputStream is = new ByteArrayInputStream(bytes); + ObjectInputStream ois = new ObjectInputStream(is); + Object o2 = ois.readObject(); + return o2; + } + + + @Test(expected=NotSerializableException.class) + public void testWithNonSerializableObject() throws IOException { + TestBean o = new TestBean(); + assertFalse(o instanceof Serializable); + assertFalse(isSerializable(o)); + + testSerialization(o); + } + + @Test + public void testWithSerializableObject() throws Exception { + int x = 5; + int y = 10; + Point p = new Point(x, y); + assertTrue(p instanceof Serializable); + + testSerialization(p); + + assertTrue(isSerializable(p)); + + Point p2 = (Point) serializeAndDeserialize(p); + assertNotSame(p, p2); + assertEquals(x, (int) p2.getX()); + assertEquals(y, (int) p2.getY()); + } + +} diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/config/DatabasePopulatorConfigUtils.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/config/DatabasePopulatorConfigUtils.java index a707d78ff33..043ccf1ad83 100644 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/config/DatabasePopulatorConfigUtils.java +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/config/DatabasePopulatorConfigUtils.java @@ -1,82 +1,82 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jdbc.config; - -import java.util.List; - -import org.springframework.beans.BeanMetadataElement; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.config.TypedStringValue; -import org.springframework.beans.factory.support.BeanDefinitionBuilder; -import org.springframework.beans.factory.support.ManagedList; -import org.springframework.jdbc.datasource.init.CompositeDatabasePopulator; -import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; -import org.springframework.util.StringUtils; -import org.springframework.util.xml.DomUtils; -import org.w3c.dom.Element; - -/** - * @author Juergen Hoeller - * @since 3.1 - */ -class DatabasePopulatorConfigUtils { - - public static void setDatabasePopulator(Element element, BeanDefinitionBuilder builder) { - List<Element> scripts = DomUtils.getChildElementsByTagName(element, "script"); - if (scripts.size() > 0) { - builder.addPropertyValue("databasePopulator", createDatabasePopulator(element, scripts, "INIT")); - builder.addPropertyValue("databaseCleaner", createDatabasePopulator(element, scripts, "DESTROY")); - } - } - - static private BeanDefinition createDatabasePopulator(Element element, List<Element> scripts, String execution) { - BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(CompositeDatabasePopulator.class); - - boolean ignoreFailedDrops = element.getAttribute("ignore-failures").equals("DROPS"); - boolean continueOnError = element.getAttribute("ignore-failures").equals("ALL"); - - ManagedList<BeanMetadataElement> delegates = new ManagedList<BeanMetadataElement>(); - for (Element scriptElement : scripts) { - String executionAttr = scriptElement.getAttribute("execution"); - if (!StringUtils.hasText(executionAttr)) { - executionAttr = "INIT"; - } - if (!execution.equals(executionAttr)) { - continue; - } - BeanDefinitionBuilder delegate = BeanDefinitionBuilder.genericBeanDefinition(ResourceDatabasePopulator.class); - delegate.addPropertyValue("ignoreFailedDrops", ignoreFailedDrops); - delegate.addPropertyValue("continueOnError", continueOnError); - - // Use a factory bean for the resources so they can be given an order if a pattern is used - BeanDefinitionBuilder resourcesFactory = BeanDefinitionBuilder.genericBeanDefinition(SortedResourcesFactoryBean.class); - resourcesFactory.addConstructorArgValue(new TypedStringValue(scriptElement.getAttribute("location"))); - delegate.addPropertyValue("scripts", resourcesFactory.getBeanDefinition()); - if (StringUtils.hasLength(scriptElement.getAttribute("encoding"))) { - delegate.addPropertyValue("sqlScriptEncoding", new TypedStringValue(scriptElement.getAttribute("encoding"))); - } - if (StringUtils.hasLength(scriptElement.getAttribute("separator"))) { - delegate.addPropertyValue("separator", new TypedStringValue(scriptElement.getAttribute("separator"))); - } - delegates.add(delegate.getBeanDefinition()); - } - builder.addPropertyValue("populators", delegates); - - return builder.getBeanDefinition(); - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.jdbc.config; + +import java.util.List; + +import org.springframework.beans.BeanMetadataElement; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.TypedStringValue; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.ManagedList; +import org.springframework.jdbc.datasource.init.CompositeDatabasePopulator; +import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; +import org.springframework.util.StringUtils; +import org.springframework.util.xml.DomUtils; +import org.w3c.dom.Element; + +/** + * @author Juergen Hoeller + * @since 3.1 + */ +class DatabasePopulatorConfigUtils { + + public static void setDatabasePopulator(Element element, BeanDefinitionBuilder builder) { + List<Element> scripts = DomUtils.getChildElementsByTagName(element, "script"); + if (scripts.size() > 0) { + builder.addPropertyValue("databasePopulator", createDatabasePopulator(element, scripts, "INIT")); + builder.addPropertyValue("databaseCleaner", createDatabasePopulator(element, scripts, "DESTROY")); + } + } + + static private BeanDefinition createDatabasePopulator(Element element, List<Element> scripts, String execution) { + BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(CompositeDatabasePopulator.class); + + boolean ignoreFailedDrops = element.getAttribute("ignore-failures").equals("DROPS"); + boolean continueOnError = element.getAttribute("ignore-failures").equals("ALL"); + + ManagedList<BeanMetadataElement> delegates = new ManagedList<BeanMetadataElement>(); + for (Element scriptElement : scripts) { + String executionAttr = scriptElement.getAttribute("execution"); + if (!StringUtils.hasText(executionAttr)) { + executionAttr = "INIT"; + } + if (!execution.equals(executionAttr)) { + continue; + } + BeanDefinitionBuilder delegate = BeanDefinitionBuilder.genericBeanDefinition(ResourceDatabasePopulator.class); + delegate.addPropertyValue("ignoreFailedDrops", ignoreFailedDrops); + delegate.addPropertyValue("continueOnError", continueOnError); + + // Use a factory bean for the resources so they can be given an order if a pattern is used + BeanDefinitionBuilder resourcesFactory = BeanDefinitionBuilder.genericBeanDefinition(SortedResourcesFactoryBean.class); + resourcesFactory.addConstructorArgValue(new TypedStringValue(scriptElement.getAttribute("location"))); + delegate.addPropertyValue("scripts", resourcesFactory.getBeanDefinition()); + if (StringUtils.hasLength(scriptElement.getAttribute("encoding"))) { + delegate.addPropertyValue("sqlScriptEncoding", new TypedStringValue(scriptElement.getAttribute("encoding"))); + } + if (StringUtils.hasLength(scriptElement.getAttribute("separator"))) { + delegate.addPropertyValue("separator", new TypedStringValue(scriptElement.getAttribute("separator"))); + } + delegates.add(delegate.getBeanDefinition()); + } + builder.addPropertyValue("populators", delegates); + + return builder.getBeanDefinition(); + } + +} diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/config/InitializeDatabaseBeanDefinitionParser.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/config/InitializeDatabaseBeanDefinitionParser.java index 5ea642fa6c7..8f7c7fd82b6 100644 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/config/InitializeDatabaseBeanDefinitionParser.java +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/config/InitializeDatabaseBeanDefinitionParser.java @@ -1,55 +1,55 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jdbc.config; - -import org.w3c.dom.Element; - -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.support.AbstractBeanDefinition; -import org.springframework.beans.factory.support.BeanDefinitionBuilder; -import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser; -import org.springframework.beans.factory.xml.ParserContext; -import org.springframework.jdbc.datasource.init.DataSourceInitializer; -import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; - -/** - * {@link org.springframework.beans.factory.xml.BeanDefinitionParser} that parses an {@code initialize-database} - * element and creates a {@link BeanDefinition} of type {@link DataSourceInitializer}. Picks up nested - * {@code script} elements and configures a {@link ResourceDatabasePopulator} for them. - * - * @author Dave Syer - * @author Juergen Hoeller - * @since 3.0 - */ -class InitializeDatabaseBeanDefinitionParser extends AbstractBeanDefinitionParser { - - @Override - protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) { - BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(DataSourceInitializer.class); - builder.addPropertyReference("dataSource", element.getAttribute("data-source")); - builder.addPropertyValue("enabled", element.getAttribute("enabled")); - DatabasePopulatorConfigUtils.setDatabasePopulator(element, builder); - builder.getRawBeanDefinition().setSource(parserContext.extractSource(element)); - return builder.getBeanDefinition(); - } - - @Override - protected boolean shouldGenerateId() { - return true; - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.jdbc.config; + +import org.w3c.dom.Element; + +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.jdbc.datasource.init.DataSourceInitializer; +import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; + +/** + * {@link org.springframework.beans.factory.xml.BeanDefinitionParser} that parses an {@code initialize-database} + * element and creates a {@link BeanDefinition} of type {@link DataSourceInitializer}. Picks up nested + * {@code script} elements and configures a {@link ResourceDatabasePopulator} for them. + * + * @author Dave Syer + * @author Juergen Hoeller + * @since 3.0 + */ +class InitializeDatabaseBeanDefinitionParser extends AbstractBeanDefinitionParser { + + @Override + protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) { + BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(DataSourceInitializer.class); + builder.addPropertyReference("dataSource", element.getAttribute("data-source")); + builder.addPropertyValue("enabled", element.getAttribute("enabled")); + DatabasePopulatorConfigUtils.setDatabasePopulator(element, builder); + builder.getRawBeanDefinition().setSource(parserContext.extractSource(element)); + return builder.getBeanDefinition(); + } + + @Override + protected boolean shouldGenerateId() { + return true; + } + +} diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/OutputStreamFactory.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/OutputStreamFactory.java index 811f389b319..848501e7e49 100644 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/OutputStreamFactory.java +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/OutputStreamFactory.java @@ -1,42 +1,42 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jdbc.datasource.embedded; - -import java.io.IOException; -import java.io.OutputStream; - -/** - * Internal helper for exposing dummy OutputStreams to embedded databases - * such as Derby, preventing the creation of a log file. - * - * @author Juergen Hoeller - * @since 3.0 - */ -public class OutputStreamFactory { - - /** - * Returns an {@link java.io.OutputStream} that ignores all data given to it. - */ - public static OutputStream getNoopOutputStream() { - return new OutputStream() { - public void write(int b) throws IOException { - // ignore the output - } - }; - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.jdbc.datasource.embedded; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * Internal helper for exposing dummy OutputStreams to embedded databases + * such as Derby, preventing the creation of a log file. + * + * @author Juergen Hoeller + * @since 3.0 + */ +public class OutputStreamFactory { + + /** + * Returns an {@link java.io.OutputStream} that ignores all data given to it. + */ + public static OutputStream getNoopOutputStream() { + return new OutputStream() { + public void write(int b) throws IOException { + // ignore the output + } + }; + } + +} diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/init/DatabasePopulatorUtils.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/init/DatabasePopulatorUtils.java index f90d94b4189..0cf23182854 100644 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/init/DatabasePopulatorUtils.java +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/init/DatabasePopulatorUtils.java @@ -1,61 +1,61 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jdbc.datasource.init; - -import java.sql.Connection; -import java.sql.SQLException; -import javax.sql.DataSource; - -import org.springframework.dao.DataAccessResourceFailureException; -import org.springframework.util.Assert; - -/** - * Utility methods for executing a DatabasePopulator. - * - * @author Juergen Hoeller - * @since 3.1 - */ -public abstract class DatabasePopulatorUtils { - - /** - * Execute the given DatabasePopulator against the given DataSource. - * @param populator the DatabasePopulator to execute - * @param dataSource the DataSource to execute against - */ - public static void execute(DatabasePopulator populator, DataSource dataSource) { - Assert.notNull(populator, "DatabasePopulator must be provided"); - Assert.notNull(dataSource, "DataSource must be provided"); - try { - Connection connection = dataSource.getConnection(); - try { - populator.populate(connection); - } - finally { - try { - connection.close(); - } - catch (SQLException ex) { - // ignore - } - } - } - catch (Exception ex) { - throw new DataAccessResourceFailureException("Failed to execute database script", ex); - } - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.jdbc.datasource.init; + +import java.sql.Connection; +import java.sql.SQLException; +import javax.sql.DataSource; + +import org.springframework.dao.DataAccessResourceFailureException; +import org.springframework.util.Assert; + +/** + * Utility methods for executing a DatabasePopulator. + * + * @author Juergen Hoeller + * @since 3.1 + */ +public abstract class DatabasePopulatorUtils { + + /** + * Execute the given DatabasePopulator against the given DataSource. + * @param populator the DatabasePopulator to execute + * @param dataSource the DataSource to execute against + */ + public static void execute(DatabasePopulator populator, DataSource dataSource) { + Assert.notNull(populator, "DatabasePopulator must be provided"); + Assert.notNull(dataSource, "DataSource must be provided"); + try { + Connection connection = dataSource.getConnection(); + try { + populator.populate(connection); + } + finally { + try { + connection.close(); + } + catch (SQLException ex) { + // ignore + } + } + } + catch (Exception ex) { + throw new DataAccessResourceFailureException("Failed to execute database script", ex); + } + } + +} diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/OracleJdbc4NativeJdbcExtractor.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/OracleJdbc4NativeJdbcExtractor.java index 123e73c8dd3..b54df136427 100644 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/OracleJdbc4NativeJdbcExtractor.java +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/OracleJdbc4NativeJdbcExtractor.java @@ -1,60 +1,60 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jdbc.support.nativejdbc; - -import java.sql.CallableStatement; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.Statement; - -/** - * A {@link Jdbc4NativeJdbcExtractor} which comes pre-configured for Oracle's JDBC driver, - * specifying the following vendor-specific API types for unwrapping: - * <ul> - * <li><code>oracle.jdbc.OracleConnection</code> - * <li><code>oracle.jdbc.OracleStatement</code> - * <li><code>oracle.jdbc.OraclePreparedStatement</code> - * <li><code>oracle.jdbc.OracleCallableStatement</code> - * <li><code>oracle.jdbc.OracleResultSet</code> - * </ul> - * - * <p>Note: This will work with any JDBC 4.0 compliant connection pool, without a need for - * connection pool specific setup. In other words, as of JDBC 4.0, NativeJdbcExtractors - * will typically be implemented for specific drivers instead of for specific pools. - * - * @author Juergen Hoeller - * @since 3.0.5 - */ -public class OracleJdbc4NativeJdbcExtractor extends Jdbc4NativeJdbcExtractor { - - @SuppressWarnings("unchecked") - public OracleJdbc4NativeJdbcExtractor() { - try { - setConnectionType((Class<Connection>) getClass().getClassLoader().loadClass("oracle.jdbc.OracleConnection")); - setStatementType((Class<Statement>) getClass().getClassLoader().loadClass("oracle.jdbc.OracleStatement")); - setPreparedStatementType((Class<PreparedStatement>) getClass().getClassLoader().loadClass("oracle.jdbc.OraclePreparedStatement")); - setCallableStatementType((Class<CallableStatement>) getClass().getClassLoader().loadClass("oracle.jdbc.OracleCallableStatement")); - setResultSetType((Class<ResultSet>) getClass().getClassLoader().loadClass("oracle.jdbc.OracleResultSet")); - } - catch (Exception ex) { - throw new IllegalStateException( - "Could not initialize OracleJdbc4NativeJdbcExtractor because Oracle API classes are not available: " + ex); - } - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.jdbc.support.nativejdbc; + +import java.sql.CallableStatement; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.Statement; + +/** + * A {@link Jdbc4NativeJdbcExtractor} which comes pre-configured for Oracle's JDBC driver, + * specifying the following vendor-specific API types for unwrapping: + * <ul> + * <li><code>oracle.jdbc.OracleConnection</code> + * <li><code>oracle.jdbc.OracleStatement</code> + * <li><code>oracle.jdbc.OraclePreparedStatement</code> + * <li><code>oracle.jdbc.OracleCallableStatement</code> + * <li><code>oracle.jdbc.OracleResultSet</code> + * </ul> + * + * <p>Note: This will work with any JDBC 4.0 compliant connection pool, without a need for + * connection pool specific setup. In other words, as of JDBC 4.0, NativeJdbcExtractors + * will typically be implemented for specific drivers instead of for specific pools. + * + * @author Juergen Hoeller + * @since 3.0.5 + */ +public class OracleJdbc4NativeJdbcExtractor extends Jdbc4NativeJdbcExtractor { + + @SuppressWarnings("unchecked") + public OracleJdbc4NativeJdbcExtractor() { + try { + setConnectionType((Class<Connection>) getClass().getClassLoader().loadClass("oracle.jdbc.OracleConnection")); + setStatementType((Class<Statement>) getClass().getClassLoader().loadClass("oracle.jdbc.OracleStatement")); + setPreparedStatementType((Class<PreparedStatement>) getClass().getClassLoader().loadClass("oracle.jdbc.OraclePreparedStatement")); + setCallableStatementType((Class<CallableStatement>) getClass().getClassLoader().loadClass("oracle.jdbc.OracleCallableStatement")); + setResultSetType((Class<ResultSet>) getClass().getClassLoader().loadClass("oracle.jdbc.OracleResultSet")); + } + catch (Exception ex) { + throw new IllegalStateException( + "Could not initialize OracleJdbc4NativeJdbcExtractor because Oracle API classes are not available: " + ex); + } + } + +} diff --git a/org.springframework.jms/src/main/java/org/springframework/jms/support/converter/MessageType.java b/org.springframework.jms/src/main/java/org/springframework/jms/support/converter/MessageType.java index cf62d34f483..8c633d61bb3 100644 --- a/org.springframework.jms/src/main/java/org/springframework/jms/support/converter/MessageType.java +++ b/org.springframework.jms/src/main/java/org/springframework/jms/support/converter/MessageType.java @@ -1,32 +1,32 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jms.support.converter; - -/** - * Constants that indicate a target message type to convert to: a - * {@link javax.jms.TextMessage}, a {@link javax.jms.BytesMessage}, - * a {@link javax.jms.MapMessage} or an {@link ObjectMessage}. - * - * @author Juergen Hoeller - * @since 3.0 - * @see MarshallingMessageConverter#setTargetType - */ -public enum MessageType { - - TEXT, BYTES, MAP, OBJECT - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.jms.support.converter; + +/** + * Constants that indicate a target message type to convert to: a + * {@link javax.jms.TextMessage}, a {@link javax.jms.BytesMessage}, + * a {@link javax.jms.MapMessage} or an {@link ObjectMessage}. + * + * @author Juergen Hoeller + * @since 3.0 + * @see MarshallingMessageConverter#setTargetType + */ +public enum MessageType { + + TEXT, BYTES, MAP, OBJECT + +} diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/LocalRegionFactoryProxy.java b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/LocalRegionFactoryProxy.java index d43196ce3fb..e0665941572 100644 --- a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/LocalRegionFactoryProxy.java +++ b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/LocalRegionFactoryProxy.java @@ -1,123 +1,123 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3; - -import java.lang.reflect.Method; -import java.util.Properties; - -import org.hibernate.cache.CacheDataDescription; -import org.hibernate.cache.CacheException; -import org.hibernate.cache.CollectionRegion; -import org.hibernate.cache.EntityRegion; -import org.hibernate.cache.QueryResultsRegion; -import org.hibernate.cache.RegionFactory; -import org.hibernate.cache.TimestampsRegion; -import org.hibernate.cache.access.AccessType; -import org.hibernate.cfg.Settings; - -import org.springframework.util.ReflectionUtils; - -/** - * Proxy for a Hibernate RegionFactory, delegating to a Spring-managed - * RegionFactory instance, determined by LocalSessionFactoryBean's - * "cacheRegionFactory" property. - * - * <p>Compatible with Hibernate 3.3 as well as Hibernate 3.5's version - * of the RegionFactory SPI. - * - * @author Juergen Hoeller - * @since 3.0 - * @see LocalSessionFactoryBean#setCacheRegionFactory - */ -public class LocalRegionFactoryProxy implements RegionFactory { - - private final RegionFactory regionFactory; - - - /** - * Standard constructor. - */ - public LocalRegionFactoryProxy() { - RegionFactory rf = (RegionFactory) LocalSessionFactoryBean.getConfigTimeRegionFactory(); - // absolutely needs thread-bound RegionFactory to initialize - if (rf == null) { - throw new IllegalStateException("No Hibernate RegionFactory found - " + - "'cacheRegionFactory' property must be set on LocalSessionFactoryBean"); - } - this.regionFactory = rf; - } - - /** - * Properties constructor: not used by this class or formally required, - * but enforced by Hibernate when reflectively instantiating a RegionFactory. - */ - public LocalRegionFactoryProxy(Properties properties) { - this(); - } - - - public void start(Settings settings, Properties properties) throws CacheException { - this.regionFactory.start(settings, properties); - } - - public void stop() { - this.regionFactory.stop(); - } - - public boolean isMinimalPutsEnabledByDefault() { - return this.regionFactory.isMinimalPutsEnabledByDefault(); - } - - public AccessType getDefaultAccessType() { - try { - Method method = RegionFactory.class.getMethod("getDefaultAccessType"); - return (AccessType) ReflectionUtils.invokeMethod(method, this.regionFactory); - } - catch (NoSuchMethodException ex) { - throw new IllegalStateException("getDefaultAccessType requires Hibernate 3.5+"); - } - } - - public long nextTimestamp() { - return this.regionFactory.nextTimestamp(); - } - - public EntityRegion buildEntityRegion(String regionName, Properties properties, CacheDataDescription metadata) - throws CacheException { - - return this.regionFactory.buildEntityRegion(regionName, properties, metadata); - } - - public CollectionRegion buildCollectionRegion(String regionName, Properties properties, - CacheDataDescription metadata) throws CacheException { - - return this.regionFactory.buildCollectionRegion(regionName, properties, metadata); - } - - public QueryResultsRegion buildQueryResultsRegion(String regionName, Properties properties) - throws CacheException { - - return this.regionFactory.buildQueryResultsRegion(regionName, properties); - } - - public TimestampsRegion buildTimestampsRegion(String regionName, Properties properties) - throws CacheException { - - return this.regionFactory.buildTimestampsRegion(regionName, properties); - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.orm.hibernate3; + +import java.lang.reflect.Method; +import java.util.Properties; + +import org.hibernate.cache.CacheDataDescription; +import org.hibernate.cache.CacheException; +import org.hibernate.cache.CollectionRegion; +import org.hibernate.cache.EntityRegion; +import org.hibernate.cache.QueryResultsRegion; +import org.hibernate.cache.RegionFactory; +import org.hibernate.cache.TimestampsRegion; +import org.hibernate.cache.access.AccessType; +import org.hibernate.cfg.Settings; + +import org.springframework.util.ReflectionUtils; + +/** + * Proxy for a Hibernate RegionFactory, delegating to a Spring-managed + * RegionFactory instance, determined by LocalSessionFactoryBean's + * "cacheRegionFactory" property. + * + * <p>Compatible with Hibernate 3.3 as well as Hibernate 3.5's version + * of the RegionFactory SPI. + * + * @author Juergen Hoeller + * @since 3.0 + * @see LocalSessionFactoryBean#setCacheRegionFactory + */ +public class LocalRegionFactoryProxy implements RegionFactory { + + private final RegionFactory regionFactory; + + + /** + * Standard constructor. + */ + public LocalRegionFactoryProxy() { + RegionFactory rf = (RegionFactory) LocalSessionFactoryBean.getConfigTimeRegionFactory(); + // absolutely needs thread-bound RegionFactory to initialize + if (rf == null) { + throw new IllegalStateException("No Hibernate RegionFactory found - " + + "'cacheRegionFactory' property must be set on LocalSessionFactoryBean"); + } + this.regionFactory = rf; + } + + /** + * Properties constructor: not used by this class or formally required, + * but enforced by Hibernate when reflectively instantiating a RegionFactory. + */ + public LocalRegionFactoryProxy(Properties properties) { + this(); + } + + + public void start(Settings settings, Properties properties) throws CacheException { + this.regionFactory.start(settings, properties); + } + + public void stop() { + this.regionFactory.stop(); + } + + public boolean isMinimalPutsEnabledByDefault() { + return this.regionFactory.isMinimalPutsEnabledByDefault(); + } + + public AccessType getDefaultAccessType() { + try { + Method method = RegionFactory.class.getMethod("getDefaultAccessType"); + return (AccessType) ReflectionUtils.invokeMethod(method, this.regionFactory); + } + catch (NoSuchMethodException ex) { + throw new IllegalStateException("getDefaultAccessType requires Hibernate 3.5+"); + } + } + + public long nextTimestamp() { + return this.regionFactory.nextTimestamp(); + } + + public EntityRegion buildEntityRegion(String regionName, Properties properties, CacheDataDescription metadata) + throws CacheException { + + return this.regionFactory.buildEntityRegion(regionName, properties, metadata); + } + + public CollectionRegion buildCollectionRegion(String regionName, Properties properties, + CacheDataDescription metadata) throws CacheException { + + return this.regionFactory.buildCollectionRegion(regionName, properties, metadata); + } + + public QueryResultsRegion buildQueryResultsRegion(String regionName, Properties properties) + throws CacheException { + + return this.regionFactory.buildQueryResultsRegion(regionName, properties); + } + + public TimestampsRegion buildTimestampsRegion(String regionName, Properties properties) + throws CacheException { + + return this.regionFactory.buildTimestampsRegion(regionName, properties); + } + +} diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBean.java b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBean.java index ca1265ce926..986e5e942f6 100644 --- a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBean.java +++ b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBean.java @@ -1,335 +1,335 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate4; - -import java.io.File; -import java.io.IOException; -import java.util.Properties; -import javax.sql.DataSource; - -import org.hibernate.SessionFactory; -import org.hibernate.cfg.NamingStrategy; - -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.context.ResourceLoaderAware; -import org.springframework.core.io.ClassPathResource; -import org.springframework.core.io.Resource; -import org.springframework.core.io.ResourceLoader; -import org.springframework.core.io.support.PathMatchingResourcePatternResolver; -import org.springframework.core.io.support.ResourcePatternResolver; -import org.springframework.core.io.support.ResourcePatternUtils; - -/** - * {@link org.springframework.beans.factory.FactoryBean} that creates a - * Hibernate {@link org.hibernate.SessionFactory}. This is the usual way to - * set up a shared Hibernate SessionFactory in a Spring application context; - * the SessionFactory can then be passed to Hibernate-based DAOs via - * dependency injection. - * - * <p><b>NOTE:</b> This variant of LocalSessionFactoryBean requires Hibernate 4.0 - * or higher. It is similar in role to the same-named class in the <code>orm.hibernate3</code> - * package. However, in practice, it is closer to <code>AnnotationSessionFactoryBean</code> - * since its core purpose is to bootstrap a <code>SessionFactory</code> from annotation scanning. - * - * @author Juergen Hoeller - * @since 3.1 - * @see #setDataSource - * @see #setPackagesToScan - */ -public class LocalSessionFactoryBean implements FactoryBean<SessionFactory>, ResourceLoaderAware, - InitializingBean, DisposableBean { - - private DataSource dataSource; - - private Resource[] configLocations; - - private String[] mappingResources; - - private Resource[] mappingLocations; - - private Resource[] cacheableMappingLocations; - - private Resource[] mappingJarLocations; - - private Resource[] mappingDirectoryLocations; - - private NamingStrategy namingStrategy; - - private Properties hibernateProperties; - - private Class<?>[] annotatedClasses; - - private String[] annotatedPackages; - - private String[] packagesToScan; - - private ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver(); - - private SessionFactory sessionFactory; - - - /** - * Set the DataSource to be used by the SessionFactory. - * If set, this will override corresponding settings in Hibernate properties. - * <p>If this is set, the Hibernate settings should not define - * a connection provider to avoid meaningless double configuration. - */ - public void setDataSource(DataSource dataSource) { - this.dataSource = dataSource; - } - - /** - * Set the location of a single Hibernate XML config file, for example as - * classpath resource "classpath:hibernate.cfg.xml". - * <p>Note: Can be omitted when all necessary properties and mapping - * resources are specified locally via this bean. - * @see org.hibernate.cfg.Configuration#configure(java.net.URL) - */ - public void setConfigLocation(Resource configLocation) { - this.configLocations = new Resource[] {configLocation}; - } - - /** - * Set the locations of multiple Hibernate XML config files, for example as - * classpath resources "classpath:hibernate.cfg.xml,classpath:extension.cfg.xml". - * <p>Note: Can be omitted when all necessary properties and mapping - * resources are specified locally via this bean. - * @see org.hibernate.cfg.Configuration#configure(java.net.URL) - */ - public void setConfigLocations(Resource[] configLocations) { - this.configLocations = configLocations; - } - - /** - * Set Hibernate mapping resources to be found in the class path, - * like "example.hbm.xml" or "mypackage/example.hbm.xml". - * Analogous to mapping entries in a Hibernate XML config file. - * Alternative to the more generic setMappingLocations method. - * <p>Can be used to add to mappings from a Hibernate XML config file, - * or to specify all mappings locally. - * @see #setMappingLocations - * @see org.hibernate.cfg.Configuration#addResource - */ - public void setMappingResources(String[] mappingResources) { - this.mappingResources = mappingResources; - } - - /** - * Set locations of Hibernate mapping files, for example as classpath - * resource "classpath:example.hbm.xml". Supports any resource location - * via Spring's resource abstraction, for example relative paths like - * "WEB-INF/mappings/example.hbm.xml" when running in an application context. - * <p>Can be used to add to mappings from a Hibernate XML config file, - * or to specify all mappings locally. - * @see org.hibernate.cfg.Configuration#addInputStream - */ - public void setMappingLocations(Resource[] mappingLocations) { - this.mappingLocations = mappingLocations; - } - - /** - * Set locations of cacheable Hibernate mapping files, for example as web app - * resource "/WEB-INF/mapping/example.hbm.xml". Supports any resource location - * via Spring's resource abstraction, as long as the resource can be resolved - * in the file system. - * <p>Can be used to add to mappings from a Hibernate XML config file, - * or to specify all mappings locally. - * @see org.hibernate.cfg.Configuration#addCacheableFile(java.io.File) - */ - public void setCacheableMappingLocations(Resource[] cacheableMappingLocations) { - this.cacheableMappingLocations = cacheableMappingLocations; - } - - /** - * Set locations of jar files that contain Hibernate mapping resources, - * like "WEB-INF/lib/example.hbm.jar". - * <p>Can be used to add to mappings from a Hibernate XML config file, - * or to specify all mappings locally. - * @see org.hibernate.cfg.Configuration#addJar(java.io.File) - */ - public void setMappingJarLocations(Resource[] mappingJarLocations) { - this.mappingJarLocations = mappingJarLocations; - } - - /** - * Set locations of directories that contain Hibernate mapping resources, - * like "WEB-INF/mappings". - * <p>Can be used to add to mappings from a Hibernate XML config file, - * or to specify all mappings locally. - * @see org.hibernate.cfg.Configuration#addDirectory(java.io.File) - */ - public void setMappingDirectoryLocations(Resource[] mappingDirectoryLocations) { - this.mappingDirectoryLocations = mappingDirectoryLocations; - } - - /** - * Set a Hibernate NamingStrategy for the SessionFactory, determining the - * physical column and table names given the info in the mapping document. - * @see org.hibernate.cfg.Configuration#setNamingStrategy - */ - public void setNamingStrategy(NamingStrategy namingStrategy) { - this.namingStrategy = namingStrategy; - } - - /** - * Set Hibernate properties, such as "hibernate.dialect". - * <p>Note: Do not specify a transaction provider here when using - * Spring-driven transactions. It is also advisable to omit connection - * provider settings and use a Spring-set DataSource instead. - * @see #setDataSource - */ - public void setHibernateProperties(Properties hibernateProperties) { - this.hibernateProperties = hibernateProperties; - } - - /** - * Return the Hibernate properties, if any. Mainly available for - * configuration through property paths that specify individual keys. - */ - public Properties getHibernateProperties() { - if (this.hibernateProperties == null) { - this.hibernateProperties = new Properties(); - } - return this.hibernateProperties; - } - - /** - * Specify annotated entity classes to register with this Hibernate SessionFactory. - * @see org.hibernate.cfg.Configuration#addAnnotatedClass(String) - */ - public void setAnnotatedClasses(Class<?>[] annotatedClasses) { - this.annotatedClasses = annotatedClasses; - } - - /** - * Specify the names of annotated packages, for which package-level - * annotation metadata will be read. - * @see org.hibernate.cfg.Configuration#addPackage(String) - */ - public void setAnnotatedPackages(String[] annotatedPackages) { - this.annotatedPackages = annotatedPackages; - } - - /** - * Specify packages to search for autodetection of your entity classes in the - * classpath. This is analogous to Spring's component-scan feature - * ({@link org.springframework.context.annotation.ClassPathBeanDefinitionScanner}). - */ - public void setPackagesToScan(String... packagesToScan) { - this.packagesToScan = packagesToScan; - } - - public void setResourceLoader(ResourceLoader resourceLoader) { - this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader); - } - - - public void afterPropertiesSet() throws IOException { - LocalSessionFactoryBuilder sfb = new LocalSessionFactoryBuilder(this.dataSource, this.resourcePatternResolver); - - if (this.configLocations != null) { - for (Resource resource : this.configLocations) { - // Load Hibernate configuration from given location. - sfb.configure(resource.getURL()); - } - } - - if (this.mappingResources != null) { - // Register given Hibernate mapping definitions, contained in resource files. - for (String mapping : this.mappingResources) { - Resource mr = new ClassPathResource(mapping.trim(), this.resourcePatternResolver.getClassLoader()); - sfb.addInputStream(mr.getInputStream()); - } - } - - if (this.mappingLocations != null) { - // Register given Hibernate mapping definitions, contained in resource files. - for (Resource resource : this.mappingLocations) { - sfb.addInputStream(resource.getInputStream()); - } - } - - if (this.cacheableMappingLocations != null) { - // Register given cacheable Hibernate mapping definitions, read from the file system. - for (Resource resource : this.cacheableMappingLocations) { - sfb.addCacheableFile(resource.getFile()); - } - } - - if (this.mappingJarLocations != null) { - // Register given Hibernate mapping definitions, contained in jar files. - for (Resource resource : this.mappingJarLocations) { - sfb.addJar(resource.getFile()); - } - } - - if (this.mappingDirectoryLocations != null) { - // Register all Hibernate mapping definitions in the given directories. - for (Resource resource : this.mappingDirectoryLocations) { - File file = resource.getFile(); - if (!file.isDirectory()) { - throw new IllegalArgumentException( - "Mapping directory location [" + resource + "] does not denote a directory"); - } - sfb.addDirectory(file); - } - } - - if (this.namingStrategy != null) { - sfb.setNamingStrategy(this.namingStrategy); - } - - if (this.hibernateProperties != null) { - sfb.addProperties(this.hibernateProperties); - } - - if (this.annotatedClasses != null) { - sfb.addAnnotatedClasses(this.annotatedClasses); - } - - if (this.annotatedPackages != null) { - sfb.addPackages(this.annotatedPackages); - } - - if (this.packagesToScan != null) { - sfb.scanPackages(this.packagesToScan); - } - - this.sessionFactory = sfb.buildSessionFactory(); - } - - - public SessionFactory getObject() { - return this.sessionFactory; - } - - public Class<?> getObjectType() { - return (this.sessionFactory != null ? this.sessionFactory.getClass() : SessionFactory.class); - } - - public boolean isSingleton() { - return true; - } - - - public void destroy() { - this.sessionFactory.close(); - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.orm.hibernate4; + +import java.io.File; +import java.io.IOException; +import java.util.Properties; +import javax.sql.DataSource; + +import org.hibernate.SessionFactory; +import org.hibernate.cfg.NamingStrategy; + +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.FactoryBean; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.context.ResourceLoaderAware; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.core.io.support.ResourcePatternResolver; +import org.springframework.core.io.support.ResourcePatternUtils; + +/** + * {@link org.springframework.beans.factory.FactoryBean} that creates a + * Hibernate {@link org.hibernate.SessionFactory}. This is the usual way to + * set up a shared Hibernate SessionFactory in a Spring application context; + * the SessionFactory can then be passed to Hibernate-based DAOs via + * dependency injection. + * + * <p><b>NOTE:</b> This variant of LocalSessionFactoryBean requires Hibernate 4.0 + * or higher. It is similar in role to the same-named class in the <code>orm.hibernate3</code> + * package. However, in practice, it is closer to <code>AnnotationSessionFactoryBean</code> + * since its core purpose is to bootstrap a <code>SessionFactory</code> from annotation scanning. + * + * @author Juergen Hoeller + * @since 3.1 + * @see #setDataSource + * @see #setPackagesToScan + */ +public class LocalSessionFactoryBean implements FactoryBean<SessionFactory>, ResourceLoaderAware, + InitializingBean, DisposableBean { + + private DataSource dataSource; + + private Resource[] configLocations; + + private String[] mappingResources; + + private Resource[] mappingLocations; + + private Resource[] cacheableMappingLocations; + + private Resource[] mappingJarLocations; + + private Resource[] mappingDirectoryLocations; + + private NamingStrategy namingStrategy; + + private Properties hibernateProperties; + + private Class<?>[] annotatedClasses; + + private String[] annotatedPackages; + + private String[] packagesToScan; + + private ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver(); + + private SessionFactory sessionFactory; + + + /** + * Set the DataSource to be used by the SessionFactory. + * If set, this will override corresponding settings in Hibernate properties. + * <p>If this is set, the Hibernate settings should not define + * a connection provider to avoid meaningless double configuration. + */ + public void setDataSource(DataSource dataSource) { + this.dataSource = dataSource; + } + + /** + * Set the location of a single Hibernate XML config file, for example as + * classpath resource "classpath:hibernate.cfg.xml". + * <p>Note: Can be omitted when all necessary properties and mapping + * resources are specified locally via this bean. + * @see org.hibernate.cfg.Configuration#configure(java.net.URL) + */ + public void setConfigLocation(Resource configLocation) { + this.configLocations = new Resource[] {configLocation}; + } + + /** + * Set the locations of multiple Hibernate XML config files, for example as + * classpath resources "classpath:hibernate.cfg.xml,classpath:extension.cfg.xml". + * <p>Note: Can be omitted when all necessary properties and mapping + * resources are specified locally via this bean. + * @see org.hibernate.cfg.Configuration#configure(java.net.URL) + */ + public void setConfigLocations(Resource[] configLocations) { + this.configLocations = configLocations; + } + + /** + * Set Hibernate mapping resources to be found in the class path, + * like "example.hbm.xml" or "mypackage/example.hbm.xml". + * Analogous to mapping entries in a Hibernate XML config file. + * Alternative to the more generic setMappingLocations method. + * <p>Can be used to add to mappings from a Hibernate XML config file, + * or to specify all mappings locally. + * @see #setMappingLocations + * @see org.hibernate.cfg.Configuration#addResource + */ + public void setMappingResources(String[] mappingResources) { + this.mappingResources = mappingResources; + } + + /** + * Set locations of Hibernate mapping files, for example as classpath + * resource "classpath:example.hbm.xml". Supports any resource location + * via Spring's resource abstraction, for example relative paths like + * "WEB-INF/mappings/example.hbm.xml" when running in an application context. + * <p>Can be used to add to mappings from a Hibernate XML config file, + * or to specify all mappings locally. + * @see org.hibernate.cfg.Configuration#addInputStream + */ + public void setMappingLocations(Resource[] mappingLocations) { + this.mappingLocations = mappingLocations; + } + + /** + * Set locations of cacheable Hibernate mapping files, for example as web app + * resource "/WEB-INF/mapping/example.hbm.xml". Supports any resource location + * via Spring's resource abstraction, as long as the resource can be resolved + * in the file system. + * <p>Can be used to add to mappings from a Hibernate XML config file, + * or to specify all mappings locally. + * @see org.hibernate.cfg.Configuration#addCacheableFile(java.io.File) + */ + public void setCacheableMappingLocations(Resource[] cacheableMappingLocations) { + this.cacheableMappingLocations = cacheableMappingLocations; + } + + /** + * Set locations of jar files that contain Hibernate mapping resources, + * like "WEB-INF/lib/example.hbm.jar". + * <p>Can be used to add to mappings from a Hibernate XML config file, + * or to specify all mappings locally. + * @see org.hibernate.cfg.Configuration#addJar(java.io.File) + */ + public void setMappingJarLocations(Resource[] mappingJarLocations) { + this.mappingJarLocations = mappingJarLocations; + } + + /** + * Set locations of directories that contain Hibernate mapping resources, + * like "WEB-INF/mappings". + * <p>Can be used to add to mappings from a Hibernate XML config file, + * or to specify all mappings locally. + * @see org.hibernate.cfg.Configuration#addDirectory(java.io.File) + */ + public void setMappingDirectoryLocations(Resource[] mappingDirectoryLocations) { + this.mappingDirectoryLocations = mappingDirectoryLocations; + } + + /** + * Set a Hibernate NamingStrategy for the SessionFactory, determining the + * physical column and table names given the info in the mapping document. + * @see org.hibernate.cfg.Configuration#setNamingStrategy + */ + public void setNamingStrategy(NamingStrategy namingStrategy) { + this.namingStrategy = namingStrategy; + } + + /** + * Set Hibernate properties, such as "hibernate.dialect". + * <p>Note: Do not specify a transaction provider here when using + * Spring-driven transactions. It is also advisable to omit connection + * provider settings and use a Spring-set DataSource instead. + * @see #setDataSource + */ + public void setHibernateProperties(Properties hibernateProperties) { + this.hibernateProperties = hibernateProperties; + } + + /** + * Return the Hibernate properties, if any. Mainly available for + * configuration through property paths that specify individual keys. + */ + public Properties getHibernateProperties() { + if (this.hibernateProperties == null) { + this.hibernateProperties = new Properties(); + } + return this.hibernateProperties; + } + + /** + * Specify annotated entity classes to register with this Hibernate SessionFactory. + * @see org.hibernate.cfg.Configuration#addAnnotatedClass(String) + */ + public void setAnnotatedClasses(Class<?>[] annotatedClasses) { + this.annotatedClasses = annotatedClasses; + } + + /** + * Specify the names of annotated packages, for which package-level + * annotation metadata will be read. + * @see org.hibernate.cfg.Configuration#addPackage(String) + */ + public void setAnnotatedPackages(String[] annotatedPackages) { + this.annotatedPackages = annotatedPackages; + } + + /** + * Specify packages to search for autodetection of your entity classes in the + * classpath. This is analogous to Spring's component-scan feature + * ({@link org.springframework.context.annotation.ClassPathBeanDefinitionScanner}). + */ + public void setPackagesToScan(String... packagesToScan) { + this.packagesToScan = packagesToScan; + } + + public void setResourceLoader(ResourceLoader resourceLoader) { + this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader); + } + + + public void afterPropertiesSet() throws IOException { + LocalSessionFactoryBuilder sfb = new LocalSessionFactoryBuilder(this.dataSource, this.resourcePatternResolver); + + if (this.configLocations != null) { + for (Resource resource : this.configLocations) { + // Load Hibernate configuration from given location. + sfb.configure(resource.getURL()); + } + } + + if (this.mappingResources != null) { + // Register given Hibernate mapping definitions, contained in resource files. + for (String mapping : this.mappingResources) { + Resource mr = new ClassPathResource(mapping.trim(), this.resourcePatternResolver.getClassLoader()); + sfb.addInputStream(mr.getInputStream()); + } + } + + if (this.mappingLocations != null) { + // Register given Hibernate mapping definitions, contained in resource files. + for (Resource resource : this.mappingLocations) { + sfb.addInputStream(resource.getInputStream()); + } + } + + if (this.cacheableMappingLocations != null) { + // Register given cacheable Hibernate mapping definitions, read from the file system. + for (Resource resource : this.cacheableMappingLocations) { + sfb.addCacheableFile(resource.getFile()); + } + } + + if (this.mappingJarLocations != null) { + // Register given Hibernate mapping definitions, contained in jar files. + for (Resource resource : this.mappingJarLocations) { + sfb.addJar(resource.getFile()); + } + } + + if (this.mappingDirectoryLocations != null) { + // Register all Hibernate mapping definitions in the given directories. + for (Resource resource : this.mappingDirectoryLocations) { + File file = resource.getFile(); + if (!file.isDirectory()) { + throw new IllegalArgumentException( + "Mapping directory location [" + resource + "] does not denote a directory"); + } + sfb.addDirectory(file); + } + } + + if (this.namingStrategy != null) { + sfb.setNamingStrategy(this.namingStrategy); + } + + if (this.hibernateProperties != null) { + sfb.addProperties(this.hibernateProperties); + } + + if (this.annotatedClasses != null) { + sfb.addAnnotatedClasses(this.annotatedClasses); + } + + if (this.annotatedPackages != null) { + sfb.addPackages(this.annotatedPackages); + } + + if (this.packagesToScan != null) { + sfb.scanPackages(this.packagesToScan); + } + + this.sessionFactory = sfb.buildSessionFactory(); + } + + + public SessionFactory getObject() { + return this.sessionFactory; + } + + public Class<?> getObjectType() { + return (this.sessionFactory != null ? this.sessionFactory.getClass() : SessionFactory.class); + } + + public boolean isSingleton() { + return true; + } + + + public void destroy() { + this.sessionFactory.close(); + } + +} diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/jpa/persistenceunit/SmartPersistenceUnitInfo.java b/org.springframework.orm/src/main/java/org/springframework/orm/jpa/persistenceunit/SmartPersistenceUnitInfo.java index 176e49556f4..1d90c222511 100644 --- a/org.springframework.orm/src/main/java/org/springframework/orm/jpa/persistenceunit/SmartPersistenceUnitInfo.java +++ b/org.springframework.orm/src/main/java/org/springframework/orm/jpa/persistenceunit/SmartPersistenceUnitInfo.java @@ -1,40 +1,40 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.jpa.persistenceunit; - -import javax.persistence.spi.PersistenceUnitInfo; - -/** - * Extension of the standard JPA PersistenceUnitInfo interface, for advanced collaboration - * between Spring's {@link org.springframework.orm.jpa.LocalEntityManagerFactoryBean} and - * {@link PersistenceUnitManager} implementations. - * - * @author Juergen Hoeller - * @since 3.0.1 - * @see PersistenceUnitManager - * @see org.springframework.orm.jpa.LocalEntityManagerFactoryBean - */ -public interface SmartPersistenceUnitInfo extends PersistenceUnitInfo { - - /** - * Set the persistence provider's own package name, for exclusion from class transformation. - * @see #addTransformer(javax.persistence.spi.ClassTransformer) - * @see #getNewTempClassLoader() - */ - void setPersistenceProviderPackageName(String persistenceProviderPackageName); - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.orm.jpa.persistenceunit; + +import javax.persistence.spi.PersistenceUnitInfo; + +/** + * Extension of the standard JPA PersistenceUnitInfo interface, for advanced collaboration + * between Spring's {@link org.springframework.orm.jpa.LocalEntityManagerFactoryBean} and + * {@link PersistenceUnitManager} implementations. + * + * @author Juergen Hoeller + * @since 3.0.1 + * @see PersistenceUnitManager + * @see org.springframework.orm.jpa.LocalEntityManagerFactoryBean + */ +public interface SmartPersistenceUnitInfo extends PersistenceUnitInfo { + + /** + * Set the persistence provider's own package name, for exclusion from class transformation. + * @see #addTransformer(javax.persistence.spi.ClassTransformer) + * @see #getNewTempClassLoader() + */ + void setPersistenceProviderPackageName(String persistenceProviderPackageName); + +} diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaSessionFactoryBean.java b/org.springframework.orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaSessionFactoryBean.java index ba3c5c4b288..a1584090ab1 100644 --- a/org.springframework.orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaSessionFactoryBean.java +++ b/org.springframework.orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaSessionFactoryBean.java @@ -1,56 +1,56 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.jpa.vendor; - -import javax.persistence.EntityManagerFactory; - -import org.hibernate.SessionFactory; -import org.hibernate.ejb.HibernateEntityManagerFactory; - -import org.springframework.beans.factory.FactoryBean; -import org.springframework.orm.jpa.EntityManagerFactoryAccessor; -import org.springframework.util.Assert; - -/** - * Simple <code>FactoryBean</code> that exposes the underlying {@link SessionFactory} - * behind a Hibernate-backed JPA {@link EntityManagerFactory}. - * - * <p>Primarily available for resolving a SessionFactory by JPA persistence unit name - * via the {@link #setPersistenceUnitName "persistenceUnitName"} bean property. - * - * @author Juergen Hoeller - * @since 3.1 - * @see #setPersistenceUnitName - * @see #setEntityManagerFactory - */ -public class HibernateJpaSessionFactoryBean extends EntityManagerFactoryAccessor implements FactoryBean<SessionFactory> { - - public SessionFactory getObject() { - EntityManagerFactory emf = getEntityManagerFactory(); - Assert.isInstanceOf(HibernateEntityManagerFactory.class, emf); - return ((HibernateEntityManagerFactory) emf).getSessionFactory(); - } - - public Class<?> getObjectType() { - return SessionFactory.class; - } - - public boolean isSingleton() { - return true; - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.orm.jpa.vendor; + +import javax.persistence.EntityManagerFactory; + +import org.hibernate.SessionFactory; +import org.hibernate.ejb.HibernateEntityManagerFactory; + +import org.springframework.beans.factory.FactoryBean; +import org.springframework.orm.jpa.EntityManagerFactoryAccessor; +import org.springframework.util.Assert; + +/** + * Simple <code>FactoryBean</code> that exposes the underlying {@link SessionFactory} + * behind a Hibernate-backed JPA {@link EntityManagerFactory}. + * + * <p>Primarily available for resolving a SessionFactory by JPA persistence unit name + * via the {@link #setPersistenceUnitName "persistenceUnitName"} bean property. + * + * @author Juergen Hoeller + * @since 3.1 + * @see #setPersistenceUnitName + * @see #setEntityManagerFactory + */ +public class HibernateJpaSessionFactoryBean extends EntityManagerFactoryAccessor implements FactoryBean<SessionFactory> { + + public SessionFactory getObject() { + EntityManagerFactory emf = getEntityManagerFactory(); + Assert.isInstanceOf(HibernateEntityManagerFactory.class, emf); + return ((HibernateEntityManagerFactory) emf).getSessionFactory(); + } + + public Class<?> getObjectType() { + return SessionFactory.class; + } + + public boolean isSingleton() { + return true; + } + +} diff --git a/org.springframework.orm/src/test/java/org/springframework/orm/hibernate3/CglibProxyBridgeMethodTests.java b/org.springframework.orm/src/test/java/org/springframework/orm/hibernate3/CglibProxyBridgeMethodTests.java index ba55810ffed..4a6c4e00a2e 100644 --- a/org.springframework.orm/src/test/java/org/springframework/orm/hibernate3/CglibProxyBridgeMethodTests.java +++ b/org.springframework.orm/src/test/java/org/springframework/orm/hibernate3/CglibProxyBridgeMethodTests.java @@ -1,73 +1,73 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.orm.hibernate3; - -import java.io.Serializable; - -import org.hibernate.proxy.HibernateProxy; -import org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer; -import org.junit.Test; - -import org.springframework.beans.BeanUtils; - -/** - * Test for compatibility of Spring's BeanUtils and its BridgeMethodResolver use - * when operating on a Hibernate-generated CGLIB proxy class. - * - * @author Arnout Engelen - * @author Juergen Hoeller - */ -public class CglibProxyBridgeMethodTests { - - @Test - public void introspectHibernateProxyForGenericClass() { - BeanUtils.getPropertyDescriptor(CglibInstantieMedewerker.class, "organisatie"); - Class<?> clazz = CGLIBLazyInitializer.getProxyFactory( - CglibInstantieMedewerker.class, new Class[] {HibernateProxy.class}); - BeanUtils.getPropertyDescriptor(clazz, "organisatie"); - } - - - public interface CglibIOrganisatie { - } - - - public class CglibOrganisatie implements CglibIOrganisatie { - } - - - public class CglibInstantie extends CglibOrganisatie { - } - - - public interface CglibIOrganisatieMedewerker<T extends CglibIOrganisatie> { - - void setOrganisatie(T organisatie); - } - - - public class CglibOrganisatieMedewerker<T extends CglibOrganisatie> implements CglibIOrganisatieMedewerker<T> { - - public void setOrganisatie(CglibOrganisatie organisatie) { - } - } - - - public class CglibInstantieMedewerker extends CglibOrganisatieMedewerker<CglibInstantie> implements Serializable { - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.orm.hibernate3; + +import java.io.Serializable; + +import org.hibernate.proxy.HibernateProxy; +import org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer; +import org.junit.Test; + +import org.springframework.beans.BeanUtils; + +/** + * Test for compatibility of Spring's BeanUtils and its BridgeMethodResolver use + * when operating on a Hibernate-generated CGLIB proxy class. + * + * @author Arnout Engelen + * @author Juergen Hoeller + */ +public class CglibProxyBridgeMethodTests { + + @Test + public void introspectHibernateProxyForGenericClass() { + BeanUtils.getPropertyDescriptor(CglibInstantieMedewerker.class, "organisatie"); + Class<?> clazz = CGLIBLazyInitializer.getProxyFactory( + CglibInstantieMedewerker.class, new Class[] {HibernateProxy.class}); + BeanUtils.getPropertyDescriptor(clazz, "organisatie"); + } + + + public interface CglibIOrganisatie { + } + + + public class CglibOrganisatie implements CglibIOrganisatie { + } + + + public class CglibInstantie extends CglibOrganisatie { + } + + + public interface CglibIOrganisatieMedewerker<T extends CglibIOrganisatie> { + + void setOrganisatie(T organisatie); + } + + + public class CglibOrganisatieMedewerker<T extends CglibOrganisatie> implements CglibIOrganisatieMedewerker<T> { + + public void setOrganisatie(CglibOrganisatie organisatie) { + } + } + + + public class CglibInstantieMedewerker extends CglibOrganisatieMedewerker<CglibInstantie> implements Serializable { + } + +} diff --git a/org.springframework.oxm/src/main/java/org/springframework/oxm/castor/CastorMappingException.java b/org.springframework.oxm/src/main/java/org/springframework/oxm/castor/CastorMappingException.java index fc881da516b..4ecc63168bd 100644 --- a/org.springframework.oxm/src/main/java/org/springframework/oxm/castor/CastorMappingException.java +++ b/org.springframework.oxm/src/main/java/org/springframework/oxm/castor/CastorMappingException.java @@ -1,39 +1,39 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.oxm.castor; - -import org.springframework.oxm.XmlMappingException; - -/** - * Exception thrown by {@link CastorMarshaller} whenever it encounters a mapping problem. - * - * @author Juergen Hoeller - * @since 3.0 - */ -public class CastorMappingException extends XmlMappingException { - - /** - * Construct a <code>CastorMappingException</code> with the specified detail message - * and nested exception. - * @param msg the detail message - * @param cause the nested exception - */ - public CastorMappingException(String msg, Throwable cause) { - super(msg, cause); - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.oxm.castor; + +import org.springframework.oxm.XmlMappingException; + +/** + * Exception thrown by {@link CastorMarshaller} whenever it encounters a mapping problem. + * + * @author Juergen Hoeller + * @since 3.0 + */ +public class CastorMappingException extends XmlMappingException { + + /** + * Construct a <code>CastorMappingException</code> with the specified detail message + * and nested exception. + * @param msg the detail message + * @param cause the nested exception + */ + public CastorMappingException(String msg, Throwable cause) { + super(msg, cause); + } + +} diff --git a/org.springframework.oxm/src/main/resources/META-INF/spring.schemas b/org.springframework.oxm/src/main/resources/META-INF/spring.schemas index e746146264a..89359c315e9 100644 --- a/org.springframework.oxm/src/main/resources/META-INF/spring.schemas +++ b/org.springframework.oxm/src/main/resources/META-INF/spring.schemas @@ -1,3 +1,3 @@ -http\://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd=org/springframework/oxm/config/spring-oxm-3.0.xsd -http\://www.springframework.org/schema/oxm/spring-oxm-3.1.xsd=org/springframework/oxm/config/spring-oxm-3.1.xsd -http\://www.springframework.org/schema/oxm/spring-oxm.xsd=org/springframework/oxm/config/spring-oxm-3.1.xsd +http\://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd=org/springframework/oxm/config/spring-oxm-3.0.xsd +http\://www.springframework.org/schema/oxm/spring-oxm-3.1.xsd=org/springframework/oxm/config/spring-oxm-3.1.xsd +http\://www.springframework.org/schema/oxm/spring-oxm.xsd=org/springframework/oxm/config/spring-oxm-3.1.xsd diff --git a/org.springframework.test/src/main/java/org/springframework/mock/web/portlet/MockCacheControl.java b/org.springframework.test/src/main/java/org/springframework/mock/web/portlet/MockCacheControl.java index 45dcae7d5ee..0ee9fbeb7c7 100644 --- a/org.springframework.test/src/main/java/org/springframework/mock/web/portlet/MockCacheControl.java +++ b/org.springframework.test/src/main/java/org/springframework/mock/web/portlet/MockCacheControl.java @@ -1,70 +1,70 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.mock.web.portlet; - -import javax.portlet.CacheControl; - -/** - * Mock implementation of the {@link javax.portlet.CacheControl} interface. - * - * @author Juergen Hoeller - * @since 3.0 - */ -public class MockCacheControl implements CacheControl { - - private int expirationTime = 0; - - private boolean publicScope = false; - - private String etag; - - private boolean useCachedContent = false; - - - public int getExpirationTime() { - return this.expirationTime; - } - - public void setExpirationTime(int time) { - this.expirationTime = time; - } - - public boolean isPublicScope() { - return this.publicScope; - } - - public void setPublicScope(boolean publicScope) { - this.publicScope = publicScope; - } - - public String getETag() { - return this.etag; - } - - public void setETag(String token) { - this.etag = token; - } - - public boolean useCachedContent() { - return this.useCachedContent; - } - - public void setUseCachedContent(boolean useCachedContent) { - this.useCachedContent = useCachedContent; - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.mock.web.portlet; + +import javax.portlet.CacheControl; + +/** + * Mock implementation of the {@link javax.portlet.CacheControl} interface. + * + * @author Juergen Hoeller + * @since 3.0 + */ +public class MockCacheControl implements CacheControl { + + private int expirationTime = 0; + + private boolean publicScope = false; + + private String etag; + + private boolean useCachedContent = false; + + + public int getExpirationTime() { + return this.expirationTime; + } + + public void setExpirationTime(int time) { + this.expirationTime = time; + } + + public boolean isPublicScope() { + return this.publicScope; + } + + public void setPublicScope(boolean publicScope) { + this.publicScope = publicScope; + } + + public String getETag() { + return this.etag; + } + + public void setETag(String token) { + this.etag = token; + } + + public boolean useCachedContent() { + return this.useCachedContent; + } + + public void setUseCachedContent(boolean useCachedContent) { + this.useCachedContent = useCachedContent; + } + +} diff --git a/org.springframework.test/src/main/java/org/springframework/mock/web/portlet/MockEvent.java b/org.springframework.test/src/main/java/org/springframework/mock/web/portlet/MockEvent.java index b58aced0ba5..0dc7efaba8d 100644 --- a/org.springframework.test/src/main/java/org/springframework/mock/web/portlet/MockEvent.java +++ b/org.springframework.test/src/main/java/org/springframework/mock/web/portlet/MockEvent.java @@ -1,88 +1,88 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.mock.web.portlet; - -import java.io.Serializable; -import javax.portlet.Event; -import javax.xml.namespace.QName; - -/** - * Mock implementation of the {@link javax.portlet.Event} interface. - * - * @author Juergen Hoeller - * @since 3.0 - * @see MockEventRequest - */ -public class MockEvent implements Event { - - private final QName name; - - private final Serializable value; - - - /** - * Create a new MockEvent with the given name. - * @param name the name of the event - */ - public MockEvent(QName name) { - this.name = name; - this.value = null; - } - - /** - * Create a new MockEvent with the given name and value. - * @param name the name of the event - * @param value the associated payload of the event - */ - public MockEvent(QName name, Serializable value) { - this.name = name; - this.value = value; - } - - /** - * Create a new MockEvent with the given name. - * @param name the name of the event - */ - public MockEvent(String name) { - this.name = new QName(name); - this.value = null; - } - - /** - * Create a new MockEvent with the given name and value. - * @param name the name of the event - * @param value the associated payload of the event - */ - public MockEvent(String name, Serializable value) { - this.name = new QName(name); - this.value = value; - } - - - public QName getQName() { - return this.name; - } - - public String getName() { - return this.name.getLocalPart(); - } - - public Serializable getValue() { - return this.value; - } - +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.mock.web.portlet; + +import java.io.Serializable; +import javax.portlet.Event; +import javax.xml.namespace.QName; + +/** + * Mock implementation of the {@link javax.portlet.Event} interface. + * + * @author Juergen Hoeller + * @since 3.0 + * @see MockEventRequest + */ +public class MockEvent implements Event { + + private final QName name; + + private final Serializable value; + + + /** + * Create a new MockEvent with the given name. + * @param name the name of the event + */ + public MockEvent(QName name) { + this.name = name; + this.value = null; + } + + /** + * Create a new MockEvent with the given name and value. + * @param name the name of the event + * @param value the associated payload of the event + */ + public MockEvent(QName name, Serializable value) { + this.name = name; + this.value = value; + } + + /** + * Create a new MockEvent with the given name. + * @param name the name of the event + */ + public MockEvent(String name) { + this.name = new QName(name); + this.value = null; + } + + /** + * Create a new MockEvent with the given name and value. + * @param name the name of the event + * @param value the associated payload of the event + */ + public MockEvent(String name, Serializable value) { + this.name = new QName(name); + this.value = value; + } + + + public QName getQName() { + return this.name; + } + + public String getName() { + return this.name.getLocalPart(); + } + + public Serializable getValue() { + return this.value; + } + } \ No newline at end of file diff --git a/org.springframework.test/src/main/java/org/springframework/mock/web/portlet/ServletWrappingPortletContext.java b/org.springframework.test/src/main/java/org/springframework/mock/web/portlet/ServletWrappingPortletContext.java index 16b3979ca75..8a88066c935 100644 --- a/org.springframework.test/src/main/java/org/springframework/mock/web/portlet/ServletWrappingPortletContext.java +++ b/org.springframework.test/src/main/java/org/springframework/mock/web/portlet/ServletWrappingPortletContext.java @@ -1,145 +1,145 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.mock.web.portlet; - -import java.io.InputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashSet; -import java.util.Set; -import javax.portlet.PortletContext; -import javax.portlet.PortletRequestDispatcher; -import javax.servlet.ServletContext; - -import org.springframework.util.Assert; - -/** - * Mock implementation of the {@link javax.portlet.PortletContext} interface, - * wrapping an underlying {@link javax.servlet.ServletContext}. - * - * @author Juergen Hoeller - * @since 3.0 - * @see MockPortletContext - */ -public class ServletWrappingPortletContext implements PortletContext { - - private final ServletContext servletContext; - - - /** - * Create a new PortletContext wrapping the given ServletContext. - * @param servletContext the ServletContext to wrap - */ - public ServletWrappingPortletContext(ServletContext servletContext) { - Assert.notNull(servletContext, "ServletContext must not be null"); - this.servletContext = servletContext; - } - - /** - * Return the underlying ServletContext that this PortletContext wraps. - */ - public final ServletContext getServletContext() { - return this.servletContext; - } - - - public String getServerInfo() { - return this.servletContext.getServerInfo(); - } - - public PortletRequestDispatcher getRequestDispatcher(String path) { - return null; - } - - public PortletRequestDispatcher getNamedDispatcher(String name) { - return null; - } - - public InputStream getResourceAsStream(String path) { - return this.servletContext.getResourceAsStream(path); - } - - public int getMajorVersion() { - return 2; - } - - public int getMinorVersion() { - return 0; - } - - public String getMimeType(String file) { - return this.servletContext.getMimeType(file); - } - - public String getRealPath(String path) { - return this.servletContext.getRealPath(path); - } - - @SuppressWarnings("unchecked") - public Set<String> getResourcePaths(String path) { - return this.servletContext.getResourcePaths(path); - } - - public URL getResource(String path) throws MalformedURLException { - return this.servletContext.getResource(path); - } - - public Object getAttribute(String name) { - return this.servletContext.getAttribute(name); - } - - @SuppressWarnings("unchecked") - public Enumeration<String> getAttributeNames() { - return this.servletContext.getAttributeNames(); - } - - public String getInitParameter(String name) { - return this.servletContext.getInitParameter(name); - } - - @SuppressWarnings("unchecked") - public Enumeration<String> getInitParameterNames() { - return this.servletContext.getInitParameterNames(); - } - - public void log(String msg) { - this.servletContext.log(msg); - } - - public void log(String message, Throwable throwable) { - this.servletContext.log(message, throwable); - } - - public void removeAttribute(String name) { - this.servletContext.removeAttribute(name); - } - - public void setAttribute(String name, Object object) { - this.servletContext.setAttribute(name, object); - } - - public String getPortletContextName() { - return this.servletContext.getServletContextName(); - } - - public Enumeration<String> getContainerRuntimeOptions() { - return Collections.enumeration(new HashSet<String>()); - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.mock.web.portlet; + +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.Set; +import javax.portlet.PortletContext; +import javax.portlet.PortletRequestDispatcher; +import javax.servlet.ServletContext; + +import org.springframework.util.Assert; + +/** + * Mock implementation of the {@link javax.portlet.PortletContext} interface, + * wrapping an underlying {@link javax.servlet.ServletContext}. + * + * @author Juergen Hoeller + * @since 3.0 + * @see MockPortletContext + */ +public class ServletWrappingPortletContext implements PortletContext { + + private final ServletContext servletContext; + + + /** + * Create a new PortletContext wrapping the given ServletContext. + * @param servletContext the ServletContext to wrap + */ + public ServletWrappingPortletContext(ServletContext servletContext) { + Assert.notNull(servletContext, "ServletContext must not be null"); + this.servletContext = servletContext; + } + + /** + * Return the underlying ServletContext that this PortletContext wraps. + */ + public final ServletContext getServletContext() { + return this.servletContext; + } + + + public String getServerInfo() { + return this.servletContext.getServerInfo(); + } + + public PortletRequestDispatcher getRequestDispatcher(String path) { + return null; + } + + public PortletRequestDispatcher getNamedDispatcher(String name) { + return null; + } + + public InputStream getResourceAsStream(String path) { + return this.servletContext.getResourceAsStream(path); + } + + public int getMajorVersion() { + return 2; + } + + public int getMinorVersion() { + return 0; + } + + public String getMimeType(String file) { + return this.servletContext.getMimeType(file); + } + + public String getRealPath(String path) { + return this.servletContext.getRealPath(path); + } + + @SuppressWarnings("unchecked") + public Set<String> getResourcePaths(String path) { + return this.servletContext.getResourcePaths(path); + } + + public URL getResource(String path) throws MalformedURLException { + return this.servletContext.getResource(path); + } + + public Object getAttribute(String name) { + return this.servletContext.getAttribute(name); + } + + @SuppressWarnings("unchecked") + public Enumeration<String> getAttributeNames() { + return this.servletContext.getAttributeNames(); + } + + public String getInitParameter(String name) { + return this.servletContext.getInitParameter(name); + } + + @SuppressWarnings("unchecked") + public Enumeration<String> getInitParameterNames() { + return this.servletContext.getInitParameterNames(); + } + + public void log(String msg) { + this.servletContext.log(msg); + } + + public void log(String message, Throwable throwable) { + this.servletContext.log(message, throwable); + } + + public void removeAttribute(String name) { + this.servletContext.removeAttribute(name); + } + + public void setAttribute(String name, Object object) { + this.servletContext.setAttribute(name, object); + } + + public String getPortletContextName() { + return this.servletContext.getServletContextName(); + } + + public Enumeration<String> getContainerRuntimeOptions() { + return Collections.enumeration(new HashSet<String>()); + } + +} diff --git a/org.springframework.test/src/test/java/org/springframework/test/context/expression/ExpressionUsageTests.java b/org.springframework.test/src/test/java/org/springframework/test/context/expression/ExpressionUsageTests.java index ddb846d4f51..723a3c1c08c 100644 --- a/org.springframework.test/src/test/java/org/springframework/test/context/expression/ExpressionUsageTests.java +++ b/org.springframework.test/src/test/java/org/springframework/test/context/expression/ExpressionUsageTests.java @@ -1,83 +1,83 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.test.context.expression; - -import static junit.framework.Assert.assertEquals; - -import java.util.Properties; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -/** - * @author Andy Clement - * @author Dave Syer - */ -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration -public class ExpressionUsageTests { - - @Autowired - @Qualifier("derived") - private Properties props; - - @Autowired - @Qualifier("andy2") - private Foo andy2; - - @Autowired - @Qualifier("andy") - private Foo andy; - - - @Test - public void testSpr5906() throws Exception { - // verify the property values have been evaluated as expressions - assertEquals("Dave", props.getProperty("user.name")); - assertEquals("Andy", props.getProperty("username")); - - // verify the property keys have been evaluated as expressions - assertEquals("exists", props.getProperty("Dave")); - assertEquals("exists also", props.getProperty("Andy")); - } - - @Test - public void testSpr5847() throws Exception { - assertEquals("Andy", andy2.getName()); - assertEquals("Andy", andy.getName()); - } - - - public static class Foo { - - private String name; - - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.test.context.expression; + +import static junit.framework.Assert.assertEquals; + +import java.util.Properties; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +/** + * @author Andy Clement + * @author Dave Syer + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration +public class ExpressionUsageTests { + + @Autowired + @Qualifier("derived") + private Properties props; + + @Autowired + @Qualifier("andy2") + private Foo andy2; + + @Autowired + @Qualifier("andy") + private Foo andy; + + + @Test + public void testSpr5906() throws Exception { + // verify the property values have been evaluated as expressions + assertEquals("Dave", props.getProperty("user.name")); + assertEquals("Andy", props.getProperty("username")); + + // verify the property keys have been evaluated as expressions + assertEquals("exists", props.getProperty("Dave")); + assertEquals("exists also", props.getProperty("Andy")); + } + + @Test + public void testSpr5847() throws Exception { + assertEquals("Andy", andy2.getName()); + assertEquals("Andy", andy.getName()); + } + + + public static class Foo { + + private String name; + + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } + +} diff --git a/org.springframework.transaction/src/main/java/org/springframework/transaction/interceptor/TransactionAspectUtils.java b/org.springframework.transaction/src/main/java/org/springframework/transaction/interceptor/TransactionAspectUtils.java index 9d07609fddc..84b082a2720 100644 --- a/org.springframework.transaction/src/main/java/org/springframework/transaction/interceptor/TransactionAspectUtils.java +++ b/org.springframework.transaction/src/main/java/org/springframework/transaction/interceptor/TransactionAspectUtils.java @@ -1,135 +1,135 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.transaction.interceptor; - -import java.lang.reflect.Method; -import java.util.Map; - -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryUtils; -import org.springframework.beans.factory.NoSuchBeanDefinitionException; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.beans.factory.support.AbstractBeanDefinition; -import org.springframework.beans.factory.support.AutowireCandidateQualifier; -import org.springframework.beans.factory.support.RootBeanDefinition; -import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.util.ObjectUtils; - -/** - * Utility methods for obtaining a PlatformTransactionManager by - * {@link TransactionAttribute#getQualifier() qualifier value}. - * - * @author Juergen Hoeller - * @since 3.0.2 - */ -public abstract class TransactionAspectUtils { - - /** - * Obtain a PlatformTransactionManager from the given BeanFactory, - * matching the given qualifier. - * @param beanFactory the BeanFactory to get the PlatformTransactionManager bean from - * @param qualifier the qualifier for selecting between multiple PlatformTransactionManager matches - * @return the chosen PlatformTransactionManager (never <code>null</code>) - * @throws IllegalStateException if no matching PlatformTransactionManager bean found - */ - public static PlatformTransactionManager getTransactionManager(BeanFactory beanFactory, String qualifier) { - if (beanFactory instanceof ConfigurableListableBeanFactory) { - // Full qualifier matching supported. - return getTransactionManager((ConfigurableListableBeanFactory) beanFactory, qualifier); - } - else if (beanFactory.containsBean(qualifier)) { - // Fallback: PlatformTransactionManager at least found by bean name. - return beanFactory.getBean(qualifier, PlatformTransactionManager.class); - } - else { - throw new IllegalStateException("No matching PlatformTransactionManager bean found for bean name '" + - qualifier + "'! (Note: Qualifier matching not supported because given BeanFactory does not " + - "implement ConfigurableListableBeanFactory.)"); - } - } - - /** - * Obtain a PlatformTransactionManager from the given BeanFactory, - * matching the given qualifier. - * @param bf the BeanFactory to get the PlatformTransactionManager bean from - * @param qualifier the qualifier for selecting between multiple PlatformTransactionManager matches - * @return the chosen PlatformTransactionManager (never <code>null</code>) - * @throws IllegalStateException if no matching PlatformTransactionManager bean found - */ - public static PlatformTransactionManager getTransactionManager(ConfigurableListableBeanFactory bf, String qualifier) { - Map<String, PlatformTransactionManager> tms = - BeanFactoryUtils.beansOfTypeIncludingAncestors(bf, PlatformTransactionManager.class); - PlatformTransactionManager chosen = null; - for (String beanName : tms.keySet()) { - if (isQualifierMatch(qualifier, beanName, bf)) { - if (chosen != null) { - throw new IllegalStateException("No unique PlatformTransactionManager bean found " + - "for qualifier '" + qualifier + "'"); - } - chosen = tms.get(beanName); - } - } - if (chosen != null) { - return chosen; - } - else { - throw new IllegalStateException("No matching PlatformTransactionManager bean found for qualifier '" + - qualifier + "' - neither qualifier match nor bean name match!"); - } - } - - /** - * Check whether we have a qualifier match for the given candidate bean. - * @param qualifier the qualifier that we are looking for - * @param beanName the name of the candidate bean - * @param bf the BeanFactory to get the bean definition from - * @return <code>true</code> if either the bean definition (in the XML case) - * or the bean's factory method (in the @Bean case) defines a matching qualifier - * value (through <qualifier<> or @Qualifier) - */ - private static boolean isQualifierMatch(String qualifier, String beanName, ConfigurableListableBeanFactory bf) { - if (bf.containsBean(beanName)) { - try { - BeanDefinition bd = bf.getMergedBeanDefinition(beanName); - if (bd instanceof AbstractBeanDefinition) { - AbstractBeanDefinition abd = (AbstractBeanDefinition) bd; - AutowireCandidateQualifier candidate = abd.getQualifier(Qualifier.class.getName()); - if ((candidate != null && qualifier.equals(candidate.getAttribute(AutowireCandidateQualifier.VALUE_KEY))) || - qualifier.equals(beanName) || ObjectUtils.containsElement(bf.getAliases(beanName), qualifier)) { - return true; - } - } - if (bd instanceof RootBeanDefinition) { - Method factoryMethod = ((RootBeanDefinition) bd).getResolvedFactoryMethod(); - if (factoryMethod != null) { - Qualifier targetAnnotation = factoryMethod.getAnnotation(Qualifier.class); - if (targetAnnotation != null && qualifier.equals(targetAnnotation.value())) { - return true; - } - } - } - } - catch (NoSuchBeanDefinitionException ex) { - // ignore - can't compare qualifiers for a manually registered singleton object - } - } - return false; - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.transaction.interceptor; + +import java.lang.reflect.Method; +import java.util.Map; + +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.BeanFactoryUtils; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.AutowireCandidateQualifier; +import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.util.ObjectUtils; + +/** + * Utility methods for obtaining a PlatformTransactionManager by + * {@link TransactionAttribute#getQualifier() qualifier value}. + * + * @author Juergen Hoeller + * @since 3.0.2 + */ +public abstract class TransactionAspectUtils { + + /** + * Obtain a PlatformTransactionManager from the given BeanFactory, + * matching the given qualifier. + * @param beanFactory the BeanFactory to get the PlatformTransactionManager bean from + * @param qualifier the qualifier for selecting between multiple PlatformTransactionManager matches + * @return the chosen PlatformTransactionManager (never <code>null</code>) + * @throws IllegalStateException if no matching PlatformTransactionManager bean found + */ + public static PlatformTransactionManager getTransactionManager(BeanFactory beanFactory, String qualifier) { + if (beanFactory instanceof ConfigurableListableBeanFactory) { + // Full qualifier matching supported. + return getTransactionManager((ConfigurableListableBeanFactory) beanFactory, qualifier); + } + else if (beanFactory.containsBean(qualifier)) { + // Fallback: PlatformTransactionManager at least found by bean name. + return beanFactory.getBean(qualifier, PlatformTransactionManager.class); + } + else { + throw new IllegalStateException("No matching PlatformTransactionManager bean found for bean name '" + + qualifier + "'! (Note: Qualifier matching not supported because given BeanFactory does not " + + "implement ConfigurableListableBeanFactory.)"); + } + } + + /** + * Obtain a PlatformTransactionManager from the given BeanFactory, + * matching the given qualifier. + * @param bf the BeanFactory to get the PlatformTransactionManager bean from + * @param qualifier the qualifier for selecting between multiple PlatformTransactionManager matches + * @return the chosen PlatformTransactionManager (never <code>null</code>) + * @throws IllegalStateException if no matching PlatformTransactionManager bean found + */ + public static PlatformTransactionManager getTransactionManager(ConfigurableListableBeanFactory bf, String qualifier) { + Map<String, PlatformTransactionManager> tms = + BeanFactoryUtils.beansOfTypeIncludingAncestors(bf, PlatformTransactionManager.class); + PlatformTransactionManager chosen = null; + for (String beanName : tms.keySet()) { + if (isQualifierMatch(qualifier, beanName, bf)) { + if (chosen != null) { + throw new IllegalStateException("No unique PlatformTransactionManager bean found " + + "for qualifier '" + qualifier + "'"); + } + chosen = tms.get(beanName); + } + } + if (chosen != null) { + return chosen; + } + else { + throw new IllegalStateException("No matching PlatformTransactionManager bean found for qualifier '" + + qualifier + "' - neither qualifier match nor bean name match!"); + } + } + + /** + * Check whether we have a qualifier match for the given candidate bean. + * @param qualifier the qualifier that we are looking for + * @param beanName the name of the candidate bean + * @param bf the BeanFactory to get the bean definition from + * @return <code>true</code> if either the bean definition (in the XML case) + * or the bean's factory method (in the @Bean case) defines a matching qualifier + * value (through <qualifier<> or @Qualifier) + */ + private static boolean isQualifierMatch(String qualifier, String beanName, ConfigurableListableBeanFactory bf) { + if (bf.containsBean(beanName)) { + try { + BeanDefinition bd = bf.getMergedBeanDefinition(beanName); + if (bd instanceof AbstractBeanDefinition) { + AbstractBeanDefinition abd = (AbstractBeanDefinition) bd; + AutowireCandidateQualifier candidate = abd.getQualifier(Qualifier.class.getName()); + if ((candidate != null && qualifier.equals(candidate.getAttribute(AutowireCandidateQualifier.VALUE_KEY))) || + qualifier.equals(beanName) || ObjectUtils.containsElement(bf.getAliases(beanName), qualifier)) { + return true; + } + } + if (bd instanceof RootBeanDefinition) { + Method factoryMethod = ((RootBeanDefinition) bd).getResolvedFactoryMethod(); + if (factoryMethod != null) { + Qualifier targetAnnotation = factoryMethod.getAnnotation(Qualifier.class); + if (targetAnnotation != null && qualifier.equals(targetAnnotation.value())) { + return true; + } + } + } + } + catch (NoSuchBeanDefinitionException ex) { + // ignore - can't compare qualifiers for a manually registered singleton object + } + } + return false; + } + +} diff --git a/org.springframework.transaction/src/main/java/org/springframework/transaction/jta/ManagedTransactionAdapter.java b/org.springframework.transaction/src/main/java/org/springframework/transaction/jta/ManagedTransactionAdapter.java index ee9938c7029..d3310106cad 100644 --- a/org.springframework.transaction/src/main/java/org/springframework/transaction/jta/ManagedTransactionAdapter.java +++ b/org.springframework.transaction/src/main/java/org/springframework/transaction/jta/ManagedTransactionAdapter.java @@ -1,89 +1,89 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.transaction.jta; - -import javax.transaction.HeuristicMixedException; -import javax.transaction.HeuristicRollbackException; -import javax.transaction.RollbackException; -import javax.transaction.Synchronization; -import javax.transaction.SystemException; -import javax.transaction.Transaction; -import javax.transaction.TransactionManager; -import javax.transaction.xa.XAResource; - -import org.springframework.util.Assert; - -/** - * Adapter for a managed JTA Transaction handle, taking a JTA - * {@link javax.transaction.TransactionManager} reference and creating - * a JTA {@link javax.transaction.Transaction} handle for it. - * - * @author Juergen Hoeller - * @since 3.0.2 - */ -public class ManagedTransactionAdapter implements Transaction { - - private final TransactionManager transactionManager; - - - /** - * Create a new ManagedTransactionAdapter for the given TransactionManager. - * @param transactionManager the JTA TransactionManager to wrap - */ - public ManagedTransactionAdapter(TransactionManager transactionManager) throws SystemException { - Assert.notNull(transactionManager, "TransactionManager must not be null"); - this.transactionManager = transactionManager; - } - - /** - * Return the JTA TransactionManager that this adapter delegates to. - */ - public final TransactionManager getTransactionManager() { - return this.transactionManager; - } - - - public void commit() throws RollbackException, HeuristicMixedException, HeuristicRollbackException, - SecurityException, SystemException { - this.transactionManager.commit(); - } - - public void rollback() throws SystemException { - this.transactionManager.rollback(); - } - - public void setRollbackOnly() throws SystemException { - this.transactionManager.setRollbackOnly(); - } - - public int getStatus() throws SystemException { - return this.transactionManager.getStatus(); - } - - public boolean enlistResource(XAResource xaRes) throws RollbackException, SystemException { - return this.transactionManager.getTransaction().enlistResource(xaRes); - } - - public boolean delistResource(XAResource xaRes, int flag) throws SystemException { - return this.transactionManager.getTransaction().delistResource(xaRes, flag); - } - - public void registerSynchronization(Synchronization sync) throws RollbackException, SystemException { - this.transactionManager.getTransaction().registerSynchronization(sync); - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.transaction.jta; + +import javax.transaction.HeuristicMixedException; +import javax.transaction.HeuristicRollbackException; +import javax.transaction.RollbackException; +import javax.transaction.Synchronization; +import javax.transaction.SystemException; +import javax.transaction.Transaction; +import javax.transaction.TransactionManager; +import javax.transaction.xa.XAResource; + +import org.springframework.util.Assert; + +/** + * Adapter for a managed JTA Transaction handle, taking a JTA + * {@link javax.transaction.TransactionManager} reference and creating + * a JTA {@link javax.transaction.Transaction} handle for it. + * + * @author Juergen Hoeller + * @since 3.0.2 + */ +public class ManagedTransactionAdapter implements Transaction { + + private final TransactionManager transactionManager; + + + /** + * Create a new ManagedTransactionAdapter for the given TransactionManager. + * @param transactionManager the JTA TransactionManager to wrap + */ + public ManagedTransactionAdapter(TransactionManager transactionManager) throws SystemException { + Assert.notNull(transactionManager, "TransactionManager must not be null"); + this.transactionManager = transactionManager; + } + + /** + * Return the JTA TransactionManager that this adapter delegates to. + */ + public final TransactionManager getTransactionManager() { + return this.transactionManager; + } + + + public void commit() throws RollbackException, HeuristicMixedException, HeuristicRollbackException, + SecurityException, SystemException { + this.transactionManager.commit(); + } + + public void rollback() throws SystemException { + this.transactionManager.rollback(); + } + + public void setRollbackOnly() throws SystemException { + this.transactionManager.setRollbackOnly(); + } + + public int getStatus() throws SystemException { + return this.transactionManager.getStatus(); + } + + public boolean enlistResource(XAResource xaRes) throws RollbackException, SystemException { + return this.transactionManager.getTransaction().enlistResource(xaRes); + } + + public boolean delistResource(XAResource xaRes, int flag) throws SystemException { + return this.transactionManager.getTransaction().delistResource(xaRes, flag); + } + + public void registerSynchronization(Synchronization sync) throws RollbackException, SystemException { + this.transactionManager.getTransaction().registerSynchronization(sync); + } + +} diff --git a/org.springframework.transaction/src/test/java/org/springframework/transaction/config/TransactionManagerConfiguration.java b/org.springframework.transaction/src/test/java/org/springframework/transaction/config/TransactionManagerConfiguration.java index bed910d0e30..11a649ad50d 100644 --- a/org.springframework.transaction/src/test/java/org/springframework/transaction/config/TransactionManagerConfiguration.java +++ b/org.springframework.transaction/src/test/java/org/springframework/transaction/config/TransactionManagerConfiguration.java @@ -1,45 +1,45 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.transaction.config; - -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.transaction.CallCountingTransactionManager; -import org.springframework.transaction.PlatformTransactionManager; - -/** - * @author Juergen Hoeller - */ -@Configuration -public class TransactionManagerConfiguration { - - @Bean - @Qualifier("synch") - public PlatformTransactionManager transactionManager1() { - return new CallCountingTransactionManager(); - } - - @Bean - @Qualifier("noSynch") - public PlatformTransactionManager transactionManager2() { - CallCountingTransactionManager tm = new CallCountingTransactionManager(); - tm.setTransactionSynchronization(CallCountingTransactionManager.SYNCHRONIZATION_NEVER); - return tm; - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.transaction.config; + +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.transaction.CallCountingTransactionManager; +import org.springframework.transaction.PlatformTransactionManager; + +/** + * @author Juergen Hoeller + */ +@Configuration +public class TransactionManagerConfiguration { + + @Bean + @Qualifier("synch") + public PlatformTransactionManager transactionManager1() { + return new CallCountingTransactionManager(); + } + + @Bean + @Qualifier("noSynch") + public PlatformTransactionManager transactionManager2() { + CallCountingTransactionManager tm = new CallCountingTransactionManager(); + tm.setTransactionSynchronization(CallCountingTransactionManager.SYNCHRONIZATION_NEVER); + return tm; + } + +} diff --git a/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/NoHandlerFoundException.java b/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/NoHandlerFoundException.java index bd5ab0c3ca7..8c24356729b 100644 --- a/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/NoHandlerFoundException.java +++ b/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/NoHandlerFoundException.java @@ -1,53 +1,53 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.portlet; - -import javax.portlet.PortletException; -import javax.portlet.PortletRequest; - -import org.springframework.core.style.StylerUtils; - -/** - * Exception to be thrown if DispatcherPortlet is unable to determine - * a corresponding handler for an incoming portlet request. - * - * @author Juergen Hoeller - * @since 3.0.5 - */ -public class NoHandlerFoundException extends PortletException { - - /** - * Constructor for NoHandlerFoundException. - * @param msg the detail message - */ - public NoHandlerFoundException(String msg) { - super(msg); - } - - /** - * Constructor for NoHandlerFoundException. - * @param msg the detail message - * @param request the current portlet request, - * for further context to be included in the exception message - */ - public NoHandlerFoundException(String msg, PortletRequest request) { - super(msg + ": mode '" + request.getPortletMode() + - "', phase '" + request.getAttribute(PortletRequest.LIFECYCLE_PHASE) + - "', parameters " + StylerUtils.style(request.getParameterMap())); - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.web.portlet; + +import javax.portlet.PortletException; +import javax.portlet.PortletRequest; + +import org.springframework.core.style.StylerUtils; + +/** + * Exception to be thrown if DispatcherPortlet is unable to determine + * a corresponding handler for an incoming portlet request. + * + * @author Juergen Hoeller + * @since 3.0.5 + */ +public class NoHandlerFoundException extends PortletException { + + /** + * Constructor for NoHandlerFoundException. + * @param msg the detail message + */ + public NoHandlerFoundException(String msg) { + super(msg); + } + + /** + * Constructor for NoHandlerFoundException. + * @param msg the detail message + * @param request the current portlet request, + * for further context to be included in the exception message + */ + public NoHandlerFoundException(String msg, PortletRequest request) { + super(msg + ": mode '" + request.getPortletMode() + + "', phase '" + request.getAttribute(PortletRequest.LIFECYCLE_PHASE) + + "', parameters " + StylerUtils.style(request.getParameterMap())); + } + +} diff --git a/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/bind/annotation/ActionMapping.java b/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/bind/annotation/ActionMapping.java index 0adb5ded1c6..28716a98104 100644 --- a/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/bind/annotation/ActionMapping.java +++ b/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/bind/annotation/ActionMapping.java @@ -1,63 +1,63 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.portlet.bind.annotation; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.web.bind.annotation.Mapping; - -/** - * Annotation for mapping Portlet action requests onto handler methods. - * - * @author Juergen Hoeller - * @since 3.0 - * @see org.springframework.web.bind.annotation.RequestMapping - */ -@Target({ElementType.METHOD}) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Mapping -public @interface ActionMapping { - - /** - * The name of the action, according to the Portlet 2.0 - * "javax.portlet.action" parameter. - * <p>If not specified, the method will be used as default handler: - * i.e. for action requests where no specific action mapping was found. - * <p>Note that all such annotated action methods only apply within the - * <code>@RequestMapping</code> constraints of the containing handler class. - * @see javax.portlet.ActionRequest#ACTION_NAME - */ - String value() default ""; - - /** - * The parameters of the mapped request, narrowing the primary mapping. - * <p>Same format for any environment: a sequence of "myParam=myValue" style - * expressions, with a request only mapped if each such parameter is found - * to have the given value. "myParam" style expressions are also supported, - * with such parameters having to be present in the request (allowed to have - * any value). Finally, "!myParam" style expressions indicate that the - * specified parameter is <i>not</i> supposed to be present in the request. - * @see org.springframework.web.bind.annotation.RequestMapping#params() - */ - String[] params() default {}; - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.web.portlet.bind.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.web.bind.annotation.Mapping; + +/** + * Annotation for mapping Portlet action requests onto handler methods. + * + * @author Juergen Hoeller + * @since 3.0 + * @see org.springframework.web.bind.annotation.RequestMapping + */ +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Mapping +public @interface ActionMapping { + + /** + * The name of the action, according to the Portlet 2.0 + * "javax.portlet.action" parameter. + * <p>If not specified, the method will be used as default handler: + * i.e. for action requests where no specific action mapping was found. + * <p>Note that all such annotated action methods only apply within the + * <code>@RequestMapping</code> constraints of the containing handler class. + * @see javax.portlet.ActionRequest#ACTION_NAME + */ + String value() default ""; + + /** + * The parameters of the mapped request, narrowing the primary mapping. + * <p>Same format for any environment: a sequence of "myParam=myValue" style + * expressions, with a request only mapped if each such parameter is found + * to have the given value. "myParam" style expressions are also supported, + * with such parameters having to be present in the request (allowed to have + * any value). Finally, "!myParam" style expressions indicate that the + * specified parameter is <i>not</i> supposed to be present in the request. + * @see org.springframework.web.bind.annotation.RequestMapping#params() + */ + String[] params() default {}; + +} diff --git a/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/bind/annotation/EventMapping.java b/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/bind/annotation/EventMapping.java index c6c605dc824..1d9e45ce986 100644 --- a/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/bind/annotation/EventMapping.java +++ b/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/bind/annotation/EventMapping.java @@ -1,52 +1,52 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.portlet.bind.annotation; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.web.bind.annotation.Mapping; - -/** - * Annotation for mapping Portlet event requests onto handler methods. - * - * @author Juergen Hoeller - * @since 3.0 - * @see org.springframework.web.bind.annotation.RequestMapping - */ -@Target({ElementType.METHOD}) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Mapping() -public @interface EventMapping { - - /** - * The name of the event to be handled. - * This name uniquely identifies an event within a portlet mode. - * <p>Typically the local name of the event, but fully qualified names - * with a "{...}" namespace part will be mapped correctly as well. - * <p>If not specified, the handler method will be invoked for any - * event request within its general mapping. - * @see javax.portlet.EventRequest#getEvent() - * @see javax.portlet.Event#getName() - */ - String value() default ""; - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.web.portlet.bind.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.web.bind.annotation.Mapping; + +/** + * Annotation for mapping Portlet event requests onto handler methods. + * + * @author Juergen Hoeller + * @since 3.0 + * @see org.springframework.web.bind.annotation.RequestMapping + */ +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Mapping() +public @interface EventMapping { + + /** + * The name of the event to be handled. + * This name uniquely identifies an event within a portlet mode. + * <p>Typically the local name of the event, but fully qualified names + * with a "{...}" namespace part will be mapped correctly as well. + * <p>If not specified, the handler method will be invoked for any + * event request within its general mapping. + * @see javax.portlet.EventRequest#getEvent() + * @see javax.portlet.Event#getName() + */ + String value() default ""; + +} diff --git a/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/bind/annotation/RenderMapping.java b/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/bind/annotation/RenderMapping.java index 7eb8b1dcf9d..13e8d31095f 100644 --- a/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/bind/annotation/RenderMapping.java +++ b/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/bind/annotation/RenderMapping.java @@ -1,62 +1,62 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.portlet.bind.annotation; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.web.bind.annotation.Mapping; - -/** - * Annotation for mapping Portlet render requests onto handler methods. - * - * @author Juergen Hoeller - * @since 3.0 - * @see org.springframework.web.bind.annotation.RequestMapping - */ -@Target({ElementType.METHOD}) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Mapping -public @interface RenderMapping { - - /** - * The window state that the annotated render method applies for. - * <p>If not specified, the render method will be invoked for any - * window state within its general mapping. - * <p>Standard Portlet spec values: "NORMAL", "MAXIMIZED", "MINIMIZED". - * Custom window states can be used as well, as supported by the portal. - * @see javax.portlet.PortletRequest#getWindowState() - */ - String value() default ""; - - /** - * The parameters of the mapped request, narrowing the primary mapping. - * <p>Same format for any environment: a sequence of "myParam=myValue" style - * expressions, with a request only mapped if each such parameter is found - * to have the given value. "myParam" style expressions are also supported, - * with such parameters having to be present in the request (allowed to have - * any value). Finally, "!myParam" style expressions indicate that the - * specified parameter is <i>not</i> supposed to be present in the request. - * @see org.springframework.web.bind.annotation.RequestMapping#params() - */ - String[] params() default {}; - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.web.portlet.bind.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.web.bind.annotation.Mapping; + +/** + * Annotation for mapping Portlet render requests onto handler methods. + * + * @author Juergen Hoeller + * @since 3.0 + * @see org.springframework.web.bind.annotation.RequestMapping + */ +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Mapping +public @interface RenderMapping { + + /** + * The window state that the annotated render method applies for. + * <p>If not specified, the render method will be invoked for any + * window state within its general mapping. + * <p>Standard Portlet spec values: "NORMAL", "MAXIMIZED", "MINIMIZED". + * Custom window states can be used as well, as supported by the portal. + * @see javax.portlet.PortletRequest#getWindowState() + */ + String value() default ""; + + /** + * The parameters of the mapped request, narrowing the primary mapping. + * <p>Same format for any environment: a sequence of "myParam=myValue" style + * expressions, with a request only mapped if each such parameter is found + * to have the given value. "myParam" style expressions are also supported, + * with such parameters having to be present in the request (allowed to have + * any value). Finally, "!myParam" style expressions indicate that the + * specified parameter is <i>not</i> supposed to be present in the request. + * @see org.springframework.web.bind.annotation.RequestMapping#params() + */ + String[] params() default {}; + +} diff --git a/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/bind/annotation/ResourceMapping.java b/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/bind/annotation/ResourceMapping.java index 250d8e7faa7..1da48192004 100644 --- a/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/bind/annotation/ResourceMapping.java +++ b/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/bind/annotation/ResourceMapping.java @@ -1,49 +1,49 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.portlet.bind.annotation; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.web.bind.annotation.Mapping; - -/** - * Annotation for mapping Portlet resource requests onto handler methods. - * - * @author Juergen Hoeller - * @since 3.0 - * @see org.springframework.web.bind.annotation.RequestMapping - */ -@Target({ElementType.METHOD}) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Mapping() -public @interface ResourceMapping { - - /** - * The id of the resource to be handled. - * This id uniquely identifies a resource within a portlet mode. - * <p>If not specified, the handler method will be invoked for any - * resource request within its general mapping. - * @see javax.portlet.ResourceRequest#getResourceID() - */ - String value() default ""; - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.web.portlet.bind.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.web.bind.annotation.Mapping; + +/** + * Annotation for mapping Portlet resource requests onto handler methods. + * + * @author Juergen Hoeller + * @since 3.0 + * @see org.springframework.web.bind.annotation.RequestMapping + */ +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Mapping() +public @interface ResourceMapping { + + /** + * The id of the resource to be handled. + * This id uniquely identifies a resource within a portlet mode. + * <p>If not specified, the handler method will be invoked for any + * resource request within its general mapping. + * @see javax.portlet.ResourceRequest#getResourceID() + */ + String value() default ""; + +} diff --git a/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/context/PortletContextScope.java b/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/context/PortletContextScope.java index 459ae6a77b9..bdd5f6846c6 100644 --- a/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/context/PortletContextScope.java +++ b/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/context/PortletContextScope.java @@ -1,111 +1,111 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.portlet.context; - -import java.util.LinkedHashMap; -import java.util.Map; -import javax.portlet.PortletContext; - -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.ObjectFactory; -import org.springframework.beans.factory.config.Scope; -import org.springframework.util.Assert; - -/** - * {@link Scope} wrapper for a PortletContext, i.e. for global web application attributes. - * - * <p>This differs from traditional Spring singletons in that it exposes attributes in the - * PortletContext. Those attributes will get destroyed whenever the entire application - * shuts down, which might be earlier or later than the shutdown of the containing Spring - * ApplicationContext. - * - * <p>The associated destruction mechanism relies on a - * {@link org.springframework.web.context.ContextCleanupListener} being registered in - * <code>web.xml</code>. Note that {@link org.springframework.web.context.ContextLoaderListener} - * includes ContextCleanupListener's functionality. - * - * <p>This scope is registered as default scope with key - * {@link org.springframework.web.context.WebApplicationContext#SCOPE_APPLICATION "application"}. - * - * @author Juergen Hoeller - * @since 3.0 - * @see org.springframework.web.context.ContextCleanupListener - */ -public class PortletContextScope implements Scope, DisposableBean { - - private final PortletContext portletContext; - - private final Map<String, Runnable> destructionCallbacks = new LinkedHashMap<String, Runnable>(); - - - /** - * Create a new Scope wrapper for the given PortletContext. - * @param PortletContext the PortletContext to wrap - */ - public PortletContextScope(PortletContext portletContext) { - Assert.notNull(portletContext, "PortletContext must not be null"); - this.portletContext = portletContext; - } - - - public Object get(String name, ObjectFactory<?> objectFactory) { - Object scopedObject = this.portletContext.getAttribute(name); - if (scopedObject == null) { - scopedObject = objectFactory.getObject(); - this.portletContext.setAttribute(name, scopedObject); - } - return scopedObject; - } - - public Object remove(String name) { - Object scopedObject = this.portletContext.getAttribute(name); - if (scopedObject != null) { - this.portletContext.removeAttribute(name); - this.destructionCallbacks.remove(name); - return scopedObject; - } - else { - return null; - } - } - - public void registerDestructionCallback(String name, Runnable callback) { - this.destructionCallbacks.put(name, callback); - } - - public Object resolveContextualObject(String key) { - return null; - } - - public String getConversationId() { - return null; - } - - - /** - * Invoke all registered destruction callbacks. - * To be called on ServletContext shutdown. - * @see org.springframework.web.context.ContextCleanupListener - */ - public void destroy() { - for (Runnable runnable : this.destructionCallbacks.values()) { - runnable.run(); - } - this.destructionCallbacks.clear(); - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.web.portlet.context; + +import java.util.LinkedHashMap; +import java.util.Map; +import javax.portlet.PortletContext; + +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.ObjectFactory; +import org.springframework.beans.factory.config.Scope; +import org.springframework.util.Assert; + +/** + * {@link Scope} wrapper for a PortletContext, i.e. for global web application attributes. + * + * <p>This differs from traditional Spring singletons in that it exposes attributes in the + * PortletContext. Those attributes will get destroyed whenever the entire application + * shuts down, which might be earlier or later than the shutdown of the containing Spring + * ApplicationContext. + * + * <p>The associated destruction mechanism relies on a + * {@link org.springframework.web.context.ContextCleanupListener} being registered in + * <code>web.xml</code>. Note that {@link org.springframework.web.context.ContextLoaderListener} + * includes ContextCleanupListener's functionality. + * + * <p>This scope is registered as default scope with key + * {@link org.springframework.web.context.WebApplicationContext#SCOPE_APPLICATION "application"}. + * + * @author Juergen Hoeller + * @since 3.0 + * @see org.springframework.web.context.ContextCleanupListener + */ +public class PortletContextScope implements Scope, DisposableBean { + + private final PortletContext portletContext; + + private final Map<String, Runnable> destructionCallbacks = new LinkedHashMap<String, Runnable>(); + + + /** + * Create a new Scope wrapper for the given PortletContext. + * @param PortletContext the PortletContext to wrap + */ + public PortletContextScope(PortletContext portletContext) { + Assert.notNull(portletContext, "PortletContext must not be null"); + this.portletContext = portletContext; + } + + + public Object get(String name, ObjectFactory<?> objectFactory) { + Object scopedObject = this.portletContext.getAttribute(name); + if (scopedObject == null) { + scopedObject = objectFactory.getObject(); + this.portletContext.setAttribute(name, scopedObject); + } + return scopedObject; + } + + public Object remove(String name) { + Object scopedObject = this.portletContext.getAttribute(name); + if (scopedObject != null) { + this.portletContext.removeAttribute(name); + this.destructionCallbacks.remove(name); + return scopedObject; + } + else { + return null; + } + } + + public void registerDestructionCallback(String name, Runnable callback) { + this.destructionCallbacks.put(name, callback); + } + + public Object resolveContextualObject(String key) { + return null; + } + + public String getConversationId() { + return null; + } + + + /** + * Invoke all registered destruction callbacks. + * To be called on ServletContext shutdown. + * @see org.springframework.web.context.ContextCleanupListener + */ + public void destroy() { + for (Runnable runnable : this.destructionCallbacks.values()) { + runnable.run(); + } + this.destructionCallbacks.clear(); + } + +} diff --git a/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/handler/PortletModeParameterLookupKey.java b/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/handler/PortletModeParameterLookupKey.java index c5273680770..dd474071725 100644 --- a/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/handler/PortletModeParameterLookupKey.java +++ b/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/handler/PortletModeParameterLookupKey.java @@ -1,64 +1,64 @@ -/* - * Copyright 2002-2008 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.portlet.handler; - -import javax.portlet.PortletMode; - -import org.springframework.util.ObjectUtils; - -/** - * Internal class used as lookup key, combining PortletMode and parameter value. - * - * @author Juergen Hoeller - */ -class PortletModeParameterLookupKey { - - private final PortletMode mode; - - private final String parameter; - - - public PortletModeParameterLookupKey(PortletMode portletMode, String parameter) { - this.mode = portletMode; - this.parameter = parameter; - } - - - @Override - public boolean equals(Object other) { - if (this == other) { - return true; - } - if (!(other instanceof PortletModeParameterLookupKey)) { - return false; - } - PortletModeParameterLookupKey otherKey = (PortletModeParameterLookupKey) other; - return (this.mode.equals(otherKey.mode) && - ObjectUtils.nullSafeEquals(this.parameter, otherKey.parameter)); - } - - @Override - public int hashCode() { - return (this.mode.hashCode() * 29 + ObjectUtils.nullSafeHashCode(this.parameter)); - } - - @Override - public String toString() { - return "Portlet mode '" + this.mode + "', parameter '" + this.parameter + "'"; - } - -} +/* + * Copyright 2002-2008 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.web.portlet.handler; + +import javax.portlet.PortletMode; + +import org.springframework.util.ObjectUtils; + +/** + * Internal class used as lookup key, combining PortletMode and parameter value. + * + * @author Juergen Hoeller + */ +class PortletModeParameterLookupKey { + + private final PortletMode mode; + + private final String parameter; + + + public PortletModeParameterLookupKey(PortletMode portletMode, String parameter) { + this.mode = portletMode; + this.parameter = parameter; + } + + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof PortletModeParameterLookupKey)) { + return false; + } + PortletModeParameterLookupKey otherKey = (PortletModeParameterLookupKey) other; + return (this.mode.equals(otherKey.mode) && + ObjectUtils.nullSafeEquals(this.parameter, otherKey.parameter)); + } + + @Override + public int hashCode() { + return (this.mode.hashCode() * 29 + ObjectUtils.nullSafeHashCode(this.parameter)); + } + + @Override + public String toString() { + return "Portlet mode '" + this.mode + "', parameter '" + this.parameter + "'"; + } + +} diff --git a/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/mvc/EventAwareController.java b/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/mvc/EventAwareController.java index fd692733e2b..bd2519ea225 100644 --- a/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/mvc/EventAwareController.java +++ b/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/mvc/EventAwareController.java @@ -1,43 +1,43 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.portlet.mvc; - -import javax.portlet.EventRequest; -import javax.portlet.EventResponse; - -/** - * Extension of the Portlet {@link Controller} interface that allows - * for handling Portlet 2.0 event requests as well. Can also be - * implemented by {@link AbstractController} subclasses. - * - * @author Juergen Hoeller - * @since 3.0 - * @see javax.portlet.EventPortlet - * @see Controller - * @see ResourceAwareController - */ -public interface EventAwareController { - - /** - * Process the event request. There is nothing to return. - * @param request current portlet event request - * @param response current portlet event response - * @throws Exception in case of errors - */ - void handleEventRequest(EventRequest request, EventResponse response) throws Exception; - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.web.portlet.mvc; + +import javax.portlet.EventRequest; +import javax.portlet.EventResponse; + +/** + * Extension of the Portlet {@link Controller} interface that allows + * for handling Portlet 2.0 event requests as well. Can also be + * implemented by {@link AbstractController} subclasses. + * + * @author Juergen Hoeller + * @since 3.0 + * @see javax.portlet.EventPortlet + * @see Controller + * @see ResourceAwareController + */ +public interface EventAwareController { + + /** + * Process the event request. There is nothing to return. + * @param request current portlet event request + * @param response current portlet event response + * @throws Exception in case of errors + */ + void handleEventRequest(EventRequest request, EventResponse response) throws Exception; + +} diff --git a/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/mvc/ResourceAwareController.java b/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/mvc/ResourceAwareController.java index 24ad45d76b9..dc35b897be3 100644 --- a/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/mvc/ResourceAwareController.java +++ b/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/mvc/ResourceAwareController.java @@ -1,48 +1,48 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.portlet.mvc; - -import javax.portlet.ResourceRequest; -import javax.portlet.ResourceResponse; - -import org.springframework.web.portlet.ModelAndView; - -/** - * Extension of the Portlet {@link Controller} interface that allows - * for handling Portlet 2.0 resource requests as well. Can also be - * implemented by {@link AbstractController} subclasses. - * - * @author Juergen Hoeller - * @since 3.0 - * @see javax.portlet.ResourceServingPortlet - * @see Controller - * @see EventAwareController - */ -public interface ResourceAwareController { - - /** - * Process the resource request and return a ModelAndView object which the DispatcherPortlet - * will render. A <code>null</code> return value is not an error: It indicates that this - * object completed request processing itself, thus there is no ModelAndView to render. - * @param request current portlet resource request - * @param response current portlet resource response - * @return a ModelAndView to render, or null if handled directly - * @throws Exception in case of errors - */ - ModelAndView handleResourceRequest(ResourceRequest request, ResourceResponse response) throws Exception; - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.web.portlet.mvc; + +import javax.portlet.ResourceRequest; +import javax.portlet.ResourceResponse; + +import org.springframework.web.portlet.ModelAndView; + +/** + * Extension of the Portlet {@link Controller} interface that allows + * for handling Portlet 2.0 resource requests as well. Can also be + * implemented by {@link AbstractController} subclasses. + * + * @author Juergen Hoeller + * @since 3.0 + * @see javax.portlet.ResourceServingPortlet + * @see Controller + * @see EventAwareController + */ +public interface ResourceAwareController { + + /** + * Process the resource request and return a ModelAndView object which the DispatcherPortlet + * will render. A <code>null</code> return value is not an error: It indicates that this + * object completed request processing itself, thus there is no ModelAndView to render. + * @param request current portlet resource request + * @param response current portlet resource response + * @return a ModelAndView to render, or null if handled directly + * @throws Exception in case of errors + */ + ModelAndView handleResourceRequest(ResourceRequest request, ResourceResponse response) throws Exception; + +} diff --git a/org.springframework.web.portlet/src/test/java/org/springframework/mock/web/portlet/MockCacheControl.java b/org.springframework.web.portlet/src/test/java/org/springframework/mock/web/portlet/MockCacheControl.java index 45dcae7d5ee..0ee9fbeb7c7 100644 --- a/org.springframework.web.portlet/src/test/java/org/springframework/mock/web/portlet/MockCacheControl.java +++ b/org.springframework.web.portlet/src/test/java/org/springframework/mock/web/portlet/MockCacheControl.java @@ -1,70 +1,70 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.mock.web.portlet; - -import javax.portlet.CacheControl; - -/** - * Mock implementation of the {@link javax.portlet.CacheControl} interface. - * - * @author Juergen Hoeller - * @since 3.0 - */ -public class MockCacheControl implements CacheControl { - - private int expirationTime = 0; - - private boolean publicScope = false; - - private String etag; - - private boolean useCachedContent = false; - - - public int getExpirationTime() { - return this.expirationTime; - } - - public void setExpirationTime(int time) { - this.expirationTime = time; - } - - public boolean isPublicScope() { - return this.publicScope; - } - - public void setPublicScope(boolean publicScope) { - this.publicScope = publicScope; - } - - public String getETag() { - return this.etag; - } - - public void setETag(String token) { - this.etag = token; - } - - public boolean useCachedContent() { - return this.useCachedContent; - } - - public void setUseCachedContent(boolean useCachedContent) { - this.useCachedContent = useCachedContent; - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.mock.web.portlet; + +import javax.portlet.CacheControl; + +/** + * Mock implementation of the {@link javax.portlet.CacheControl} interface. + * + * @author Juergen Hoeller + * @since 3.0 + */ +public class MockCacheControl implements CacheControl { + + private int expirationTime = 0; + + private boolean publicScope = false; + + private String etag; + + private boolean useCachedContent = false; + + + public int getExpirationTime() { + return this.expirationTime; + } + + public void setExpirationTime(int time) { + this.expirationTime = time; + } + + public boolean isPublicScope() { + return this.publicScope; + } + + public void setPublicScope(boolean publicScope) { + this.publicScope = publicScope; + } + + public String getETag() { + return this.etag; + } + + public void setETag(String token) { + this.etag = token; + } + + public boolean useCachedContent() { + return this.useCachedContent; + } + + public void setUseCachedContent(boolean useCachedContent) { + this.useCachedContent = useCachedContent; + } + +} diff --git a/org.springframework.web.portlet/src/test/java/org/springframework/mock/web/portlet/MockEvent.java b/org.springframework.web.portlet/src/test/java/org/springframework/mock/web/portlet/MockEvent.java index b58aced0ba5..0dc7efaba8d 100644 --- a/org.springframework.web.portlet/src/test/java/org/springframework/mock/web/portlet/MockEvent.java +++ b/org.springframework.web.portlet/src/test/java/org/springframework/mock/web/portlet/MockEvent.java @@ -1,88 +1,88 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.mock.web.portlet; - -import java.io.Serializable; -import javax.portlet.Event; -import javax.xml.namespace.QName; - -/** - * Mock implementation of the {@link javax.portlet.Event} interface. - * - * @author Juergen Hoeller - * @since 3.0 - * @see MockEventRequest - */ -public class MockEvent implements Event { - - private final QName name; - - private final Serializable value; - - - /** - * Create a new MockEvent with the given name. - * @param name the name of the event - */ - public MockEvent(QName name) { - this.name = name; - this.value = null; - } - - /** - * Create a new MockEvent with the given name and value. - * @param name the name of the event - * @param value the associated payload of the event - */ - public MockEvent(QName name, Serializable value) { - this.name = name; - this.value = value; - } - - /** - * Create a new MockEvent with the given name. - * @param name the name of the event - */ - public MockEvent(String name) { - this.name = new QName(name); - this.value = null; - } - - /** - * Create a new MockEvent with the given name and value. - * @param name the name of the event - * @param value the associated payload of the event - */ - public MockEvent(String name, Serializable value) { - this.name = new QName(name); - this.value = value; - } - - - public QName getQName() { - return this.name; - } - - public String getName() { - return this.name.getLocalPart(); - } - - public Serializable getValue() { - return this.value; - } - +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.mock.web.portlet; + +import java.io.Serializable; +import javax.portlet.Event; +import javax.xml.namespace.QName; + +/** + * Mock implementation of the {@link javax.portlet.Event} interface. + * + * @author Juergen Hoeller + * @since 3.0 + * @see MockEventRequest + */ +public class MockEvent implements Event { + + private final QName name; + + private final Serializable value; + + + /** + * Create a new MockEvent with the given name. + * @param name the name of the event + */ + public MockEvent(QName name) { + this.name = name; + this.value = null; + } + + /** + * Create a new MockEvent with the given name and value. + * @param name the name of the event + * @param value the associated payload of the event + */ + public MockEvent(QName name, Serializable value) { + this.name = name; + this.value = value; + } + + /** + * Create a new MockEvent with the given name. + * @param name the name of the event + */ + public MockEvent(String name) { + this.name = new QName(name); + this.value = null; + } + + /** + * Create a new MockEvent with the given name and value. + * @param name the name of the event + * @param value the associated payload of the event + */ + public MockEvent(String name, Serializable value) { + this.name = new QName(name); + this.value = value; + } + + + public QName getQName() { + return this.name; + } + + public String getName() { + return this.name.getLocalPart(); + } + + public Serializable getValue() { + return this.value; + } + } \ No newline at end of file diff --git a/org.springframework.web.portlet/src/test/java/org/springframework/mock/web/portlet/ServletWrappingPortletContext.java b/org.springframework.web.portlet/src/test/java/org/springframework/mock/web/portlet/ServletWrappingPortletContext.java index d796d3ea453..a333984f48a 100644 --- a/org.springframework.web.portlet/src/test/java/org/springframework/mock/web/portlet/ServletWrappingPortletContext.java +++ b/org.springframework.web.portlet/src/test/java/org/springframework/mock/web/portlet/ServletWrappingPortletContext.java @@ -1,145 +1,145 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.mock.web.portlet; - -import java.io.InputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashSet; -import java.util.Set; -import javax.portlet.PortletContext; -import javax.portlet.PortletRequestDispatcher; -import javax.servlet.ServletContext; - -import org.springframework.util.Assert; - -/** - * Mock implementation of the {@link javax.portlet.PortletContext} interface, - * wrapping an underlying {@link javax.servlet.ServletContext}. - * - * @author Juergen Hoeller - * @since 3.0 - * @see org.springframework.mock.web.portlet.MockPortletContext - */ -public class ServletWrappingPortletContext implements PortletContext { - - private final ServletContext servletContext; - - - /** - * Create a new PortletContext wrapping the given ServletContext. - * @param servletContext the ServletContext to wrap - */ - public ServletWrappingPortletContext(ServletContext servletContext) { - Assert.notNull(servletContext, "ServletContext must not be null"); - this.servletContext = servletContext; - } - - /** - * Return the underlying ServletContext that this PortletContext wraps. - */ - public final ServletContext getServletContext() { - return this.servletContext; - } - - - public String getServerInfo() { - return this.servletContext.getServerInfo(); - } - - public PortletRequestDispatcher getRequestDispatcher(String path) { - return null; - } - - public PortletRequestDispatcher getNamedDispatcher(String name) { - return null; - } - - public InputStream getResourceAsStream(String path) { - return this.servletContext.getResourceAsStream(path); - } - - public int getMajorVersion() { - return 2; - } - - public int getMinorVersion() { - return 0; - } - - public String getMimeType(String file) { - return this.servletContext.getMimeType(file); - } - - public String getRealPath(String path) { - return this.servletContext.getRealPath(path); - } - - @SuppressWarnings("unchecked") - public Set<String> getResourcePaths(String path) { - return this.servletContext.getResourcePaths(path); - } - - public URL getResource(String path) throws MalformedURLException { - return this.servletContext.getResource(path); - } - - public Object getAttribute(String name) { - return this.servletContext.getAttribute(name); - } - - @SuppressWarnings("unchecked") - public Enumeration<String> getAttributeNames() { - return this.servletContext.getAttributeNames(); - } - - public String getInitParameter(String name) { - return this.servletContext.getInitParameter(name); - } - - @SuppressWarnings("unchecked") - public Enumeration<String> getInitParameterNames() { - return this.servletContext.getInitParameterNames(); - } - - public void log(String msg) { - this.servletContext.log(msg); - } - - public void log(String message, Throwable throwable) { - this.servletContext.log(message, throwable); - } - - public void removeAttribute(String name) { - this.servletContext.removeAttribute(name); - } - - public void setAttribute(String name, Object object) { - this.servletContext.setAttribute(name, object); - } - - public String getPortletContextName() { - return this.servletContext.getServletContextName(); - } - - public Enumeration<String> getContainerRuntimeOptions() { - return Collections.enumeration(new HashSet<String>()); - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.mock.web.portlet; + +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.Set; +import javax.portlet.PortletContext; +import javax.portlet.PortletRequestDispatcher; +import javax.servlet.ServletContext; + +import org.springframework.util.Assert; + +/** + * Mock implementation of the {@link javax.portlet.PortletContext} interface, + * wrapping an underlying {@link javax.servlet.ServletContext}. + * + * @author Juergen Hoeller + * @since 3.0 + * @see org.springframework.mock.web.portlet.MockPortletContext + */ +public class ServletWrappingPortletContext implements PortletContext { + + private final ServletContext servletContext; + + + /** + * Create a new PortletContext wrapping the given ServletContext. + * @param servletContext the ServletContext to wrap + */ + public ServletWrappingPortletContext(ServletContext servletContext) { + Assert.notNull(servletContext, "ServletContext must not be null"); + this.servletContext = servletContext; + } + + /** + * Return the underlying ServletContext that this PortletContext wraps. + */ + public final ServletContext getServletContext() { + return this.servletContext; + } + + + public String getServerInfo() { + return this.servletContext.getServerInfo(); + } + + public PortletRequestDispatcher getRequestDispatcher(String path) { + return null; + } + + public PortletRequestDispatcher getNamedDispatcher(String name) { + return null; + } + + public InputStream getResourceAsStream(String path) { + return this.servletContext.getResourceAsStream(path); + } + + public int getMajorVersion() { + return 2; + } + + public int getMinorVersion() { + return 0; + } + + public String getMimeType(String file) { + return this.servletContext.getMimeType(file); + } + + public String getRealPath(String path) { + return this.servletContext.getRealPath(path); + } + + @SuppressWarnings("unchecked") + public Set<String> getResourcePaths(String path) { + return this.servletContext.getResourcePaths(path); + } + + public URL getResource(String path) throws MalformedURLException { + return this.servletContext.getResource(path); + } + + public Object getAttribute(String name) { + return this.servletContext.getAttribute(name); + } + + @SuppressWarnings("unchecked") + public Enumeration<String> getAttributeNames() { + return this.servletContext.getAttributeNames(); + } + + public String getInitParameter(String name) { + return this.servletContext.getInitParameter(name); + } + + @SuppressWarnings("unchecked") + public Enumeration<String> getInitParameterNames() { + return this.servletContext.getInitParameterNames(); + } + + public void log(String msg) { + this.servletContext.log(msg); + } + + public void log(String message, Throwable throwable) { + this.servletContext.log(message, throwable); + } + + public void removeAttribute(String name) { + this.servletContext.removeAttribute(name); + } + + public void setAttribute(String name, Object object) { + this.servletContext.setAttribute(name, object); + } + + public String getPortletContextName() { + return this.servletContext.getServletContextName(); + } + + public Enumeration<String> getContainerRuntimeOptions() { + return Collections.enumeration(new HashSet<String>()); + } + +} diff --git a/org.springframework.web.portlet/src/test/java/org/springframework/web/portlet/context/PortletApplicationContextScopeTests.java b/org.springframework.web.portlet/src/test/java/org/springframework/web/portlet/context/PortletApplicationContextScopeTests.java index 64201e768a1..452ddb3c520 100644 --- a/org.springframework.web.portlet/src/test/java/org/springframework/web/portlet/context/PortletApplicationContextScopeTests.java +++ b/org.springframework.web.portlet/src/test/java/org/springframework/web/portlet/context/PortletApplicationContextScopeTests.java @@ -1,128 +1,128 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.portlet.context; - -import javax.portlet.PortletContext; -import javax.portlet.PortletSession; -import javax.servlet.ServletContextEvent; - -import static org.junit.Assert.*; -import org.junit.Test; - -import org.springframework.beans.DerivedTestBean; -import org.springframework.beans.factory.support.GenericBeanDefinition; -import org.springframework.mock.web.MockServletContext; -import org.springframework.mock.web.portlet.MockRenderRequest; -import org.springframework.mock.web.portlet.ServletWrappingPortletContext; -import org.springframework.web.context.ContextCleanupListener; -import org.springframework.web.context.WebApplicationContext; -import org.springframework.web.context.request.RequestContextHolder; -import org.springframework.web.context.support.GenericWebApplicationContext; - -/** - * @author Juergen Hoeller - */ -public class PortletApplicationContextScopeTests { - - private static final String NAME = "scoped"; - - - private ConfigurablePortletApplicationContext initApplicationContext(String scope) { - MockServletContext sc = new MockServletContext(); - GenericWebApplicationContext rac = new GenericWebApplicationContext(sc); - rac.refresh(); - PortletContext pc = new ServletWrappingPortletContext(sc); - StaticPortletApplicationContext ac = new StaticPortletApplicationContext(); - ac.setParent(rac); - ac.setPortletContext(pc); - GenericBeanDefinition bd = new GenericBeanDefinition(); - bd.setBeanClass(DerivedTestBean.class); - bd.setScope(scope); - ac.registerBeanDefinition(NAME, bd); - ac.refresh(); - return ac; - } - - @Test - public void testRequestScope() { - WebApplicationContext ac = initApplicationContext(WebApplicationContext.SCOPE_REQUEST); - MockRenderRequest request = new MockRenderRequest(); - PortletRequestAttributes requestAttributes = new PortletRequestAttributes(request); - RequestContextHolder.setRequestAttributes(requestAttributes); - try { - assertNull(request.getAttribute(NAME)); - DerivedTestBean bean = ac.getBean(NAME, DerivedTestBean.class); - assertSame(bean, request.getAttribute(NAME)); - assertSame(bean, ac.getBean(NAME)); - requestAttributes.requestCompleted(); - assertTrue(bean.wasDestroyed()); - } - finally { - RequestContextHolder.setRequestAttributes(null); - } - } - - @Test - public void testSessionScope() { - WebApplicationContext ac = initApplicationContext(WebApplicationContext.SCOPE_SESSION); - MockRenderRequest request = new MockRenderRequest(); - PortletRequestAttributes requestAttributes = new PortletRequestAttributes(request); - RequestContextHolder.setRequestAttributes(requestAttributes); - try { - assertNull(request.getPortletSession().getAttribute(NAME)); - DerivedTestBean bean = ac.getBean(NAME, DerivedTestBean.class); - assertSame(bean, request.getPortletSession().getAttribute(NAME)); - assertSame(bean, ac.getBean(NAME)); - request.getPortletSession().invalidate(); - assertTrue(bean.wasDestroyed()); - } - finally { - RequestContextHolder.setRequestAttributes(null); - } - } - - @Test - public void testGlobalSessionScope() { - WebApplicationContext ac = initApplicationContext(WebApplicationContext.SCOPE_GLOBAL_SESSION); - MockRenderRequest request = new MockRenderRequest(); - PortletRequestAttributes requestAttributes = new PortletRequestAttributes(request); - RequestContextHolder.setRequestAttributes(requestAttributes); - try { - assertNull(request.getPortletSession().getAttribute(NAME, PortletSession.APPLICATION_SCOPE)); - DerivedTestBean bean = ac.getBean(NAME, DerivedTestBean.class); - assertSame(bean, request.getPortletSession().getAttribute(NAME, PortletSession.APPLICATION_SCOPE)); - assertSame(bean, ac.getBean(NAME)); - request.getPortletSession().invalidate(); - assertTrue(bean.wasDestroyed()); - } - finally { - RequestContextHolder.setRequestAttributes(null); - } - } - - @Test - public void testApplicationScope() { - ConfigurablePortletApplicationContext ac = initApplicationContext(WebApplicationContext.SCOPE_APPLICATION); - assertNull(ac.getPortletContext().getAttribute(NAME)); - DerivedTestBean bean = ac.getBean(NAME, DerivedTestBean.class); - assertSame(bean, ac.getPortletContext().getAttribute(NAME)); - assertSame(bean, ac.getBean(NAME)); - new ContextCleanupListener().contextDestroyed(new ServletContextEvent(ac.getServletContext())); - assertTrue(bean.wasDestroyed()); - } - +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.web.portlet.context; + +import javax.portlet.PortletContext; +import javax.portlet.PortletSession; +import javax.servlet.ServletContextEvent; + +import static org.junit.Assert.*; +import org.junit.Test; + +import org.springframework.beans.DerivedTestBean; +import org.springframework.beans.factory.support.GenericBeanDefinition; +import org.springframework.mock.web.MockServletContext; +import org.springframework.mock.web.portlet.MockRenderRequest; +import org.springframework.mock.web.portlet.ServletWrappingPortletContext; +import org.springframework.web.context.ContextCleanupListener; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.support.GenericWebApplicationContext; + +/** + * @author Juergen Hoeller + */ +public class PortletApplicationContextScopeTests { + + private static final String NAME = "scoped"; + + + private ConfigurablePortletApplicationContext initApplicationContext(String scope) { + MockServletContext sc = new MockServletContext(); + GenericWebApplicationContext rac = new GenericWebApplicationContext(sc); + rac.refresh(); + PortletContext pc = new ServletWrappingPortletContext(sc); + StaticPortletApplicationContext ac = new StaticPortletApplicationContext(); + ac.setParent(rac); + ac.setPortletContext(pc); + GenericBeanDefinition bd = new GenericBeanDefinition(); + bd.setBeanClass(DerivedTestBean.class); + bd.setScope(scope); + ac.registerBeanDefinition(NAME, bd); + ac.refresh(); + return ac; + } + + @Test + public void testRequestScope() { + WebApplicationContext ac = initApplicationContext(WebApplicationContext.SCOPE_REQUEST); + MockRenderRequest request = new MockRenderRequest(); + PortletRequestAttributes requestAttributes = new PortletRequestAttributes(request); + RequestContextHolder.setRequestAttributes(requestAttributes); + try { + assertNull(request.getAttribute(NAME)); + DerivedTestBean bean = ac.getBean(NAME, DerivedTestBean.class); + assertSame(bean, request.getAttribute(NAME)); + assertSame(bean, ac.getBean(NAME)); + requestAttributes.requestCompleted(); + assertTrue(bean.wasDestroyed()); + } + finally { + RequestContextHolder.setRequestAttributes(null); + } + } + + @Test + public void testSessionScope() { + WebApplicationContext ac = initApplicationContext(WebApplicationContext.SCOPE_SESSION); + MockRenderRequest request = new MockRenderRequest(); + PortletRequestAttributes requestAttributes = new PortletRequestAttributes(request); + RequestContextHolder.setRequestAttributes(requestAttributes); + try { + assertNull(request.getPortletSession().getAttribute(NAME)); + DerivedTestBean bean = ac.getBean(NAME, DerivedTestBean.class); + assertSame(bean, request.getPortletSession().getAttribute(NAME)); + assertSame(bean, ac.getBean(NAME)); + request.getPortletSession().invalidate(); + assertTrue(bean.wasDestroyed()); + } + finally { + RequestContextHolder.setRequestAttributes(null); + } + } + + @Test + public void testGlobalSessionScope() { + WebApplicationContext ac = initApplicationContext(WebApplicationContext.SCOPE_GLOBAL_SESSION); + MockRenderRequest request = new MockRenderRequest(); + PortletRequestAttributes requestAttributes = new PortletRequestAttributes(request); + RequestContextHolder.setRequestAttributes(requestAttributes); + try { + assertNull(request.getPortletSession().getAttribute(NAME, PortletSession.APPLICATION_SCOPE)); + DerivedTestBean bean = ac.getBean(NAME, DerivedTestBean.class); + assertSame(bean, request.getPortletSession().getAttribute(NAME, PortletSession.APPLICATION_SCOPE)); + assertSame(bean, ac.getBean(NAME)); + request.getPortletSession().invalidate(); + assertTrue(bean.wasDestroyed()); + } + finally { + RequestContextHolder.setRequestAttributes(null); + } + } + + @Test + public void testApplicationScope() { + ConfigurablePortletApplicationContext ac = initApplicationContext(WebApplicationContext.SCOPE_APPLICATION); + assertNull(ac.getPortletContext().getAttribute(NAME)); + DerivedTestBean bean = ac.getBean(NAME, DerivedTestBean.class); + assertSame(bean, ac.getPortletContext().getAttribute(NAME)); + assertSame(bean, ac.getBean(NAME)); + new ContextCleanupListener().contextDestroyed(new ServletContextEvent(ac.getServletContext())); + assertTrue(bean.wasDestroyed()); + } + } \ No newline at end of file diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/condition/package-info.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/condition/package-info.java index 1bd63109886..b318bed079c 100644 --- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/condition/package-info.java +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/condition/package-info.java @@ -1,8 +1,8 @@ - -/** - * - * Common MVC logic for matching incoming requests based on conditions. - * - */ -package org.springframework.web.servlet.mvc.condition; - + +/** + * + * Common MVC logic for matching incoming requests based on conditions. + * + */ +package org.springframework.web.servlet.mvc.condition; + diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/package-info.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/package-info.java index 32a80b04711..ead0f5afed4 100644 --- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/package-info.java +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/package-info.java @@ -1,10 +1,10 @@ - -/** - * - * MVC infrastructure for annotation-based handler method processing, - * building on the <code>org.springframework.web.method.annotation</code> package. - * Entry points are {@link RequestMappingHandlerMapping} and {@link RequestMappingHandlerAdapter}. - * - */ -package org.springframework.web.servlet.mvc.method.annotation; - + +/** + * + * MVC infrastructure for annotation-based handler method processing, + * building on the <code>org.springframework.web.method.annotation</code> package. + * Entry points are {@link RequestMappingHandlerMapping} and {@link RequestMappingHandlerAdapter}. + * + */ +package org.springframework.web.servlet.mvc.method.annotation; + diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/package-info.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/package-info.java index abeebd10398..039fcb7b357 100644 --- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/package-info.java +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/package-info.java @@ -1,9 +1,9 @@ - -/** - * - * Servlet-based infrastructure for handler method processing, - * building on the <code>org.springframework.web.method</code> package. - * - */ -package org.springframework.web.servlet.mvc.method; - + +/** + * + * Servlet-based infrastructure for handler method processing, + * building on the <code>org.springframework.web.method</code> package. + * + */ +package org.springframework.web.servlet.mvc.method; + diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/view/tiles2/SpringTilesApplicationContextFactory.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/view/tiles2/SpringTilesApplicationContextFactory.java index db630ce561b..da6383a7347 100644 --- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/view/tiles2/SpringTilesApplicationContextFactory.java +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/view/tiles2/SpringTilesApplicationContextFactory.java @@ -1,112 +1,112 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.servlet.view.tiles2; - -import java.io.IOException; -import java.net.URL; -import java.util.Enumeration; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Set; -import javax.servlet.ServletContext; - -import org.apache.tiles.Initializable; -import org.apache.tiles.TilesApplicationContext; -import org.apache.tiles.context.AbstractTilesApplicationContextFactory; -import org.apache.tiles.servlet.context.ServletTilesApplicationContext; - -import org.springframework.core.io.Resource; -import org.springframework.core.io.support.ResourcePatternResolver; -import org.springframework.web.context.support.ServletContextResourcePatternResolver; - -/** - * Spring-specific subclass of the standard Tiles AbstractTilesApplicationContextFactory, - * passing given properties through as Tiles init-param map. - * - * @author Juergen Hoeller - * @since 3.0 - * @see TilesConfigurer#setTilesProperties - */ -public class SpringTilesApplicationContextFactory extends AbstractTilesApplicationContextFactory - implements Initializable { - - private Map<String, String> params; - - public void init(Map<String, String> params) { - this.params = params; - } - - public TilesApplicationContext createApplicationContext(Object context) { - return new SpringWildcardServletTilesApplicationContext((ServletContext) context, this.params); - } - - - /** - * Custom subclass of the standard Tiles WildcardServletTilesApplicationContext, - * passing given properties through as Tiles init-param map. - */ - private static class SpringWildcardServletTilesApplicationContext extends ServletTilesApplicationContext { - - private final Map<String, String> mergedInitParams; - - private final ResourcePatternResolver resolver; - - public SpringWildcardServletTilesApplicationContext(ServletContext servletContext, Map<String, String> params) { - super(servletContext); - this.mergedInitParams = new LinkedHashMap<String, String>(); - Enumeration initParamNames = servletContext.getInitParameterNames(); - while (initParamNames.hasMoreElements()) { - String initParamName = (String) initParamNames.nextElement(); - this.mergedInitParams.put(initParamName, servletContext.getInitParameter(initParamName)); - } - if (params != null) { - this.mergedInitParams.putAll(params); - } - this.resolver = new ServletContextResourcePatternResolver(servletContext); - } - - @Override - public Map<String, String> getInitParams() { - return this.mergedInitParams; - } - - @Override - public URL getResource(String path) throws IOException { - URL retValue = null; - Set<URL> urlSet = getResources(path); - if (urlSet != null && !urlSet.isEmpty()) { - retValue = urlSet.iterator().next(); - } - return retValue; - } - - @Override - public Set<URL> getResources(String path) throws IOException { - Set<URL> urlSet = null; - Resource[] resources = this.resolver.getResources(path); - if (resources != null && resources.length > 0) { - urlSet = new HashSet<URL>(); - for (Resource resource : resources) { - urlSet.add(resource.getURL()); - } - } - return urlSet; - } - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.web.servlet.view.tiles2; + +import java.io.IOException; +import java.net.URL; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; +import javax.servlet.ServletContext; + +import org.apache.tiles.Initializable; +import org.apache.tiles.TilesApplicationContext; +import org.apache.tiles.context.AbstractTilesApplicationContextFactory; +import org.apache.tiles.servlet.context.ServletTilesApplicationContext; + +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.ResourcePatternResolver; +import org.springframework.web.context.support.ServletContextResourcePatternResolver; + +/** + * Spring-specific subclass of the standard Tiles AbstractTilesApplicationContextFactory, + * passing given properties through as Tiles init-param map. + * + * @author Juergen Hoeller + * @since 3.0 + * @see TilesConfigurer#setTilesProperties + */ +public class SpringTilesApplicationContextFactory extends AbstractTilesApplicationContextFactory + implements Initializable { + + private Map<String, String> params; + + public void init(Map<String, String> params) { + this.params = params; + } + + public TilesApplicationContext createApplicationContext(Object context) { + return new SpringWildcardServletTilesApplicationContext((ServletContext) context, this.params); + } + + + /** + * Custom subclass of the standard Tiles WildcardServletTilesApplicationContext, + * passing given properties through as Tiles init-param map. + */ + private static class SpringWildcardServletTilesApplicationContext extends ServletTilesApplicationContext { + + private final Map<String, String> mergedInitParams; + + private final ResourcePatternResolver resolver; + + public SpringWildcardServletTilesApplicationContext(ServletContext servletContext, Map<String, String> params) { + super(servletContext); + this.mergedInitParams = new LinkedHashMap<String, String>(); + Enumeration initParamNames = servletContext.getInitParameterNames(); + while (initParamNames.hasMoreElements()) { + String initParamName = (String) initParamNames.nextElement(); + this.mergedInitParams.put(initParamName, servletContext.getInitParameter(initParamName)); + } + if (params != null) { + this.mergedInitParams.putAll(params); + } + this.resolver = new ServletContextResourcePatternResolver(servletContext); + } + + @Override + public Map<String, String> getInitParams() { + return this.mergedInitParams; + } + + @Override + public URL getResource(String path) throws IOException { + URL retValue = null; + Set<URL> urlSet = getResources(path); + if (urlSet != null && !urlSet.isEmpty()) { + retValue = urlSet.iterator().next(); + } + return retValue; + } + + @Override + public Set<URL> getResources(String path) throws IOException { + Set<URL> urlSet = null; + Resource[] resources = this.resolver.getResources(path); + if (resources != null && resources.length > 0) { + urlSet = new HashSet<URL>(); + for (Resource resource : resources) { + urlSet.add(resource.getURL()); + } + } + return urlSet; + } + } + +} diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/DelegatingServletInputStream.java b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/DelegatingServletInputStream.java index 22dd38281ea..b083e95b27e 100644 --- a/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/DelegatingServletInputStream.java +++ b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/DelegatingServletInputStream.java @@ -1,66 +1,66 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.mock.web; - -import java.io.IOException; -import java.io.InputStream; -import javax.servlet.ServletInputStream; - -import org.springframework.util.Assert; - -/** - * Delegating implementation of {@link javax.servlet.ServletInputStream}. - * - * <p>Used by {@link MockHttpServletRequest}; typically not directly - * used for testing application controllers. - * - * @author Juergen Hoeller - * @since 1.0.2 - * @see MockHttpServletRequest - */ -public class DelegatingServletInputStream extends ServletInputStream { - - private final InputStream sourceStream; - - - /** - * Create a DelegatingServletInputStream for the given source stream. - * @param sourceStream the source stream (never <code>null</code>) - */ - public DelegatingServletInputStream(InputStream sourceStream) { - Assert.notNull(sourceStream, "Source InputStream must not be null"); - this.sourceStream = sourceStream; - } - - /** - * Return the underlying source stream (never <code>null</code>). - */ - public final InputStream getSourceStream() { - return this.sourceStream; - } - - - public int read() throws IOException { - return this.sourceStream.read(); - } - - public void close() throws IOException { - super.close(); - this.sourceStream.close(); - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.mock.web; + +import java.io.IOException; +import java.io.InputStream; +import javax.servlet.ServletInputStream; + +import org.springframework.util.Assert; + +/** + * Delegating implementation of {@link javax.servlet.ServletInputStream}. + * + * <p>Used by {@link MockHttpServletRequest}; typically not directly + * used for testing application controllers. + * + * @author Juergen Hoeller + * @since 1.0.2 + * @see MockHttpServletRequest + */ +public class DelegatingServletInputStream extends ServletInputStream { + + private final InputStream sourceStream; + + + /** + * Create a DelegatingServletInputStream for the given source stream. + * @param sourceStream the source stream (never <code>null</code>) + */ + public DelegatingServletInputStream(InputStream sourceStream) { + Assert.notNull(sourceStream, "Source InputStream must not be null"); + this.sourceStream = sourceStream; + } + + /** + * Return the underlying source stream (never <code>null</code>). + */ + public final InputStream getSourceStream() { + return this.sourceStream; + } + + + public int read() throws IOException { + return this.sourceStream.read(); + } + + public void close() throws IOException { + super.close(); + this.sourceStream.close(); + } + +} diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/DelegatingServletOutputStream.java b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/DelegatingServletOutputStream.java index ccf5ce3f219..edc42c2d842 100644 --- a/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/DelegatingServletOutputStream.java +++ b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/DelegatingServletOutputStream.java @@ -1,74 +1,74 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.mock.web; - -import java.io.IOException; -import java.io.OutputStream; -import javax.servlet.ServletOutputStream; - -import org.springframework.util.Assert; - -/** - * Delegating implementation of {@link javax.servlet.ServletOutputStream}. - * - * <p>Used by {@link MockHttpServletResponse}; typically not directly - * used for testing application controllers. - * - * @author Juergen Hoeller - * @since 1.0.2 - * @see MockHttpServletResponse - */ -public class DelegatingServletOutputStream extends ServletOutputStream { - - private final OutputStream targetStream; - - - /** - * Create a DelegatingServletOutputStream for the given target stream. - * @param targetStream the target stream (never <code>null</code>) - */ - public DelegatingServletOutputStream(OutputStream targetStream) { - Assert.notNull(targetStream, "Target OutputStream must not be null"); - this.targetStream = targetStream; - } - - /** - * Return the underlying target stream (never <code>null</code>). - */ - public final OutputStream getTargetStream() { - return this.targetStream; - } - - - @Override - public void write(int b) throws IOException { - this.targetStream.write(b); - } - - @Override - public void flush() throws IOException { - super.flush(); - this.targetStream.flush(); - } - - @Override - public void close() throws IOException { - super.close(); - this.targetStream.close(); - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.mock.web; + +import java.io.IOException; +import java.io.OutputStream; +import javax.servlet.ServletOutputStream; + +import org.springframework.util.Assert; + +/** + * Delegating implementation of {@link javax.servlet.ServletOutputStream}. + * + * <p>Used by {@link MockHttpServletResponse}; typically not directly + * used for testing application controllers. + * + * @author Juergen Hoeller + * @since 1.0.2 + * @see MockHttpServletResponse + */ +public class DelegatingServletOutputStream extends ServletOutputStream { + + private final OutputStream targetStream; + + + /** + * Create a DelegatingServletOutputStream for the given target stream. + * @param targetStream the target stream (never <code>null</code>) + */ + public DelegatingServletOutputStream(OutputStream targetStream) { + Assert.notNull(targetStream, "Target OutputStream must not be null"); + this.targetStream = targetStream; + } + + /** + * Return the underlying target stream (never <code>null</code>). + */ + public final OutputStream getTargetStream() { + return this.targetStream; + } + + + @Override + public void write(int b) throws IOException { + this.targetStream.write(b); + } + + @Override + public void flush() throws IOException { + super.flush(); + this.targetStream.flush(); + } + + @Override + public void close() throws IOException { + super.close(); + this.targetStream.close(); + } + +} diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/HeaderValueHolder.java b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/HeaderValueHolder.java index 48224a00d21..afe74ad8f0f 100644 --- a/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/HeaderValueHolder.java +++ b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/HeaderValueHolder.java @@ -1,96 +1,96 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.mock.web; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import org.springframework.util.Assert; -import org.springframework.util.CollectionUtils; - -/** - * Internal helper class that serves as value holder for request headers. - * - * @author Juergen Hoeller - * @author Rick Evans - * @since 2.0.1 - */ -class HeaderValueHolder { - - private final List<Object> values = new LinkedList<Object>(); - - - public void setValue(Object value) { - this.values.clear(); - this.values.add(value); - } - - public void addValue(Object value) { - this.values.add(value); - } - - public void addValues(Collection<?> values) { - this.values.addAll(values); - } - - public void addValueArray(Object values) { - CollectionUtils.mergeArrayIntoCollection(values, this.values); - } - - public List<Object> getValues() { - return Collections.unmodifiableList(this.values); - } - - public List<String> getStringValues() { - List<String> stringList = new ArrayList<String>(this.values.size()); - for (Object value : this.values) { - stringList.add(value.toString()); - } - return Collections.unmodifiableList(stringList); - } - - public Object getValue() { - return (!this.values.isEmpty() ? this.values.get(0) : null); - } - - public String getStringValue() { - return (!this.values.isEmpty() ? this.values.get(0).toString() : null); - } - - - /** - * Find a HeaderValueHolder by name, ignoring casing. - * @param headers the Map of header names to HeaderValueHolders - * @param name the name of the desired header - * @return the corresponding HeaderValueHolder, - * or <code>null</code> if none found - */ - public static HeaderValueHolder getByName(Map<String, HeaderValueHolder> headers, String name) { - Assert.notNull(name, "Header name must not be null"); - for (String headerName : headers.keySet()) { - if (headerName.equalsIgnoreCase(name)) { - return headers.get(headerName); - } - } - return null; - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.mock.web; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; + +/** + * Internal helper class that serves as value holder for request headers. + * + * @author Juergen Hoeller + * @author Rick Evans + * @since 2.0.1 + */ +class HeaderValueHolder { + + private final List<Object> values = new LinkedList<Object>(); + + + public void setValue(Object value) { + this.values.clear(); + this.values.add(value); + } + + public void addValue(Object value) { + this.values.add(value); + } + + public void addValues(Collection<?> values) { + this.values.addAll(values); + } + + public void addValueArray(Object values) { + CollectionUtils.mergeArrayIntoCollection(values, this.values); + } + + public List<Object> getValues() { + return Collections.unmodifiableList(this.values); + } + + public List<String> getStringValues() { + List<String> stringList = new ArrayList<String>(this.values.size()); + for (Object value : this.values) { + stringList.add(value.toString()); + } + return Collections.unmodifiableList(stringList); + } + + public Object getValue() { + return (!this.values.isEmpty() ? this.values.get(0) : null); + } + + public String getStringValue() { + return (!this.values.isEmpty() ? this.values.get(0).toString() : null); + } + + + /** + * Find a HeaderValueHolder by name, ignoring casing. + * @param headers the Map of header names to HeaderValueHolders + * @param name the name of the desired header + * @return the corresponding HeaderValueHolder, + * or <code>null</code> if none found + */ + public static HeaderValueHolder getByName(Map<String, HeaderValueHolder> headers, String name) { + Assert.notNull(name, "Header name must not be null"); + for (String headerName : headers.keySet()) { + if (headerName.equalsIgnoreCase(name)) { + return headers.get(headerName); + } + } + return null; + } + +} diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockBodyContent.java b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockBodyContent.java index 25b6fae60b5..3fb6ca77030 100644 --- a/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockBodyContent.java +++ b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockBodyContent.java @@ -1,197 +1,197 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.mock.web; - -import java.io.IOException; -import java.io.Reader; -import java.io.StringReader; -import java.io.Writer; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.jsp.JspWriter; -import javax.servlet.jsp.tagext.BodyContent; - -/** - * Mock implementation of the {@link javax.servlet.jsp.tagext.BodyContent} class. - * - * <p>Used for testing the web framework; only necessary for testing - * applications when testing custom JSP tags. - * - * @author Juergen Hoeller - * @since 2.5 - */ -public class MockBodyContent extends BodyContent { - - private final String content; - - - /** - * Create a MockBodyContent for the given response. - * @param content the body content to expose - * @param response the servlet response to wrap - */ - public MockBodyContent(String content, HttpServletResponse response) { - this(content, response, null); - } - - /** - * Create a MockBodyContent for the given response. - * @param content the body content to expose - * @param targetWriter the target Writer to wrap - */ - public MockBodyContent(String content, Writer targetWriter) { - this(content, null, targetWriter); - } - - /** - * Create a MockBodyContent for the given response. - * @param content the body content to expose - * @param response the servlet response to wrap - * @param targetWriter the target Writer to wrap - */ - public MockBodyContent(String content, HttpServletResponse response, Writer targetWriter) { - super(adaptJspWriter(targetWriter, response)); - this.content = content; - } - - private static JspWriter adaptJspWriter(Writer targetWriter, HttpServletResponse response) { - if (targetWriter instanceof JspWriter) { - return (JspWriter) targetWriter; - } - else { - return new MockJspWriter(response, targetWriter); - } - } - - - public Reader getReader() { - return new StringReader(this.content); - } - - public String getString() { - return this.content; - } - - public void writeOut(Writer writer) throws IOException { - writer.write(this.content); - } - - - //--------------------------------------------------------------------- - // Delegating implementations of JspWriter's abstract methods - //--------------------------------------------------------------------- - - public void clear() throws IOException { - getEnclosingWriter().clear(); - } - - public void clearBuffer() throws IOException { - getEnclosingWriter().clearBuffer(); - } - - public void close() throws IOException { - getEnclosingWriter().close(); - } - - public int getRemaining() { - return getEnclosingWriter().getRemaining(); - } - - public void newLine() throws IOException { - getEnclosingWriter().println(); - } - - public void write(char value[], int offset, int length) throws IOException { - getEnclosingWriter().write(value, offset, length); - } - - public void print(boolean value) throws IOException { - getEnclosingWriter().print(value); - } - - public void print(char value) throws IOException { - getEnclosingWriter().print(value); - } - - public void print(char[] value) throws IOException { - getEnclosingWriter().print(value); - } - - public void print(double value) throws IOException { - getEnclosingWriter().print(value); - } - - public void print(float value) throws IOException { - getEnclosingWriter().print(value); - } - - public void print(int value) throws IOException { - getEnclosingWriter().print(value); - } - - public void print(long value) throws IOException { - getEnclosingWriter().print(value); - } - - public void print(Object value) throws IOException { - getEnclosingWriter().print(value); - } - - public void print(String value) throws IOException { - getEnclosingWriter().print(value); - } - - public void println() throws IOException { - getEnclosingWriter().println(); - } - - public void println(boolean value) throws IOException { - getEnclosingWriter().println(value); - } - - public void println(char value) throws IOException { - getEnclosingWriter().println(value); - } - - public void println(char[] value) throws IOException { - getEnclosingWriter().println(value); - } - - public void println(double value) throws IOException { - getEnclosingWriter().println(value); - } - - public void println(float value) throws IOException { - getEnclosingWriter().println(value); - } - - public void println(int value) throws IOException { - getEnclosingWriter().println(value); - } - - public void println(long value) throws IOException { - getEnclosingWriter().println(value); - } - - public void println(Object value) throws IOException { - getEnclosingWriter().println(value); - } - - public void println(String value) throws IOException { - getEnclosingWriter().println(value); - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.mock.web; + +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; +import java.io.Writer; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.jsp.JspWriter; +import javax.servlet.jsp.tagext.BodyContent; + +/** + * Mock implementation of the {@link javax.servlet.jsp.tagext.BodyContent} class. + * + * <p>Used for testing the web framework; only necessary for testing + * applications when testing custom JSP tags. + * + * @author Juergen Hoeller + * @since 2.5 + */ +public class MockBodyContent extends BodyContent { + + private final String content; + + + /** + * Create a MockBodyContent for the given response. + * @param content the body content to expose + * @param response the servlet response to wrap + */ + public MockBodyContent(String content, HttpServletResponse response) { + this(content, response, null); + } + + /** + * Create a MockBodyContent for the given response. + * @param content the body content to expose + * @param targetWriter the target Writer to wrap + */ + public MockBodyContent(String content, Writer targetWriter) { + this(content, null, targetWriter); + } + + /** + * Create a MockBodyContent for the given response. + * @param content the body content to expose + * @param response the servlet response to wrap + * @param targetWriter the target Writer to wrap + */ + public MockBodyContent(String content, HttpServletResponse response, Writer targetWriter) { + super(adaptJspWriter(targetWriter, response)); + this.content = content; + } + + private static JspWriter adaptJspWriter(Writer targetWriter, HttpServletResponse response) { + if (targetWriter instanceof JspWriter) { + return (JspWriter) targetWriter; + } + else { + return new MockJspWriter(response, targetWriter); + } + } + + + public Reader getReader() { + return new StringReader(this.content); + } + + public String getString() { + return this.content; + } + + public void writeOut(Writer writer) throws IOException { + writer.write(this.content); + } + + + //--------------------------------------------------------------------- + // Delegating implementations of JspWriter's abstract methods + //--------------------------------------------------------------------- + + public void clear() throws IOException { + getEnclosingWriter().clear(); + } + + public void clearBuffer() throws IOException { + getEnclosingWriter().clearBuffer(); + } + + public void close() throws IOException { + getEnclosingWriter().close(); + } + + public int getRemaining() { + return getEnclosingWriter().getRemaining(); + } + + public void newLine() throws IOException { + getEnclosingWriter().println(); + } + + public void write(char value[], int offset, int length) throws IOException { + getEnclosingWriter().write(value, offset, length); + } + + public void print(boolean value) throws IOException { + getEnclosingWriter().print(value); + } + + public void print(char value) throws IOException { + getEnclosingWriter().print(value); + } + + public void print(char[] value) throws IOException { + getEnclosingWriter().print(value); + } + + public void print(double value) throws IOException { + getEnclosingWriter().print(value); + } + + public void print(float value) throws IOException { + getEnclosingWriter().print(value); + } + + public void print(int value) throws IOException { + getEnclosingWriter().print(value); + } + + public void print(long value) throws IOException { + getEnclosingWriter().print(value); + } + + public void print(Object value) throws IOException { + getEnclosingWriter().print(value); + } + + public void print(String value) throws IOException { + getEnclosingWriter().print(value); + } + + public void println() throws IOException { + getEnclosingWriter().println(); + } + + public void println(boolean value) throws IOException { + getEnclosingWriter().println(value); + } + + public void println(char value) throws IOException { + getEnclosingWriter().println(value); + } + + public void println(char[] value) throws IOException { + getEnclosingWriter().println(value); + } + + public void println(double value) throws IOException { + getEnclosingWriter().println(value); + } + + public void println(float value) throws IOException { + getEnclosingWriter().println(value); + } + + public void println(int value) throws IOException { + getEnclosingWriter().println(value); + } + + public void println(long value) throws IOException { + getEnclosingWriter().println(value); + } + + public void println(Object value) throws IOException { + getEnclosingWriter().println(value); + } + + public void println(String value) throws IOException { + getEnclosingWriter().println(value); + } + +} diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockFilterChain.java b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockFilterChain.java index b59b233e122..3f74cac8b54 100644 --- a/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockFilterChain.java +++ b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockFilterChain.java @@ -1,70 +1,70 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.mock.web; - -import javax.servlet.FilterChain; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; - -import org.springframework.util.Assert; - -/** - * Mock implementation of the {@link javax.servlet.FilterConfig} interface. - * - * <p>Used for testing the web framework; also usefol for testing - * custom {@link javax.servlet.Filter} implementations. - * - * @author Juergen Hoeller - * @since 2.0.3 - * @see MockFilterConfig - * @see PassThroughFilterChain - */ -public class MockFilterChain implements FilterChain { - - private ServletRequest request; - - private ServletResponse response; - - - /** - * Records the request and response. - */ - public void doFilter(ServletRequest request, ServletResponse response) { - Assert.notNull(request, "Request must not be null"); - Assert.notNull(response, "Response must not be null"); - if (this.request != null) { - throw new IllegalStateException("This FilterChain has already been called!"); - } - this.request = request; - this.response = response; - } - - /** - * Return the request that {@link #doFilter} has been called with. - */ - public ServletRequest getRequest() { - return this.request; - } - - /** - * Return the response that {@link #doFilter} has been called with. - */ - public ServletResponse getResponse() { - return this.response; - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.mock.web; + +import javax.servlet.FilterChain; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; + +import org.springframework.util.Assert; + +/** + * Mock implementation of the {@link javax.servlet.FilterConfig} interface. + * + * <p>Used for testing the web framework; also usefol for testing + * custom {@link javax.servlet.Filter} implementations. + * + * @author Juergen Hoeller + * @since 2.0.3 + * @see MockFilterConfig + * @see PassThroughFilterChain + */ +public class MockFilterChain implements FilterChain { + + private ServletRequest request; + + private ServletResponse response; + + + /** + * Records the request and response. + */ + public void doFilter(ServletRequest request, ServletResponse response) { + Assert.notNull(request, "Request must not be null"); + Assert.notNull(response, "Response must not be null"); + if (this.request != null) { + throw new IllegalStateException("This FilterChain has already been called!"); + } + this.request = request; + this.response = response; + } + + /** + * Return the request that {@link #doFilter} has been called with. + */ + public ServletRequest getRequest() { + return this.request; + } + + /** + * Return the response that {@link #doFilter} has been called with. + */ + public ServletResponse getResponse() { + return this.response; + } + +} diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockHttpServletRequest.java b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockHttpServletRequest.java index f493d553cf1..5d23662a3fc 100644 --- a/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockHttpServletRequest.java +++ b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockHttpServletRequest.java @@ -1,948 +1,948 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.mock.web; - -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.io.UnsupportedEncodingException; -import java.security.Principal; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; - -import javax.servlet.AsyncContext; -import javax.servlet.DispatcherType; -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletInputStream; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; -import javax.servlet.http.Part; - -import org.springframework.util.Assert; -import org.springframework.util.LinkedCaseInsensitiveMap; - -/** - * Mock implementation of the {@link javax.servlet.http.HttpServletRequest} - * interface. Supports the Servlet 2.5 API level; throws - * {@link UnsupportedOperationException} for all methods introduced in Servlet 3.0. - * - * <p>Used for testing the web framework; also useful for testing - * application controllers. - * - * @author Juergen Hoeller - * @author Rod Johnson - * @author Rick Evans - * @author Mark Fisher - * @author Chris Beams - * @since 1.0.2 - */ -public class MockHttpServletRequest implements HttpServletRequest { - - /** - * The default protocol: 'http'. - */ - public static final String DEFAULT_PROTOCOL = "http"; - - /** - * The default server address: '127.0.0.1'. - */ - public static final String DEFAULT_SERVER_ADDR = "127.0.0.1"; - - /** - * The default server name: 'localhost'. - */ - public static final String DEFAULT_SERVER_NAME = "localhost"; - - /** - * The default server port: '80'. - */ - public static final int DEFAULT_SERVER_PORT = 80; - - /** - * The default remote address: '127.0.0.1'. - */ - public static final String DEFAULT_REMOTE_ADDR = "127.0.0.1"; - - /** - * The default remote host: 'localhost'. - */ - public static final String DEFAULT_REMOTE_HOST = "localhost"; - - private static final String CONTENT_TYPE_HEADER = "Content-Type"; - - private static final String CHARSET_PREFIX = "charset="; - - - private boolean active = true; - - - //--------------------------------------------------------------------- - // ServletRequest properties - //--------------------------------------------------------------------- - - private final Map<String, Object> attributes = new LinkedHashMap<String, Object>(); - - private String characterEncoding; - - private byte[] content; - - private String contentType; - - private final Map<String, String[]> parameters = new LinkedHashMap<String, String[]>(16); - - private String protocol = DEFAULT_PROTOCOL; - - private String scheme = DEFAULT_PROTOCOL; - - private String serverName = DEFAULT_SERVER_NAME; - - private int serverPort = DEFAULT_SERVER_PORT; - - private String remoteAddr = DEFAULT_REMOTE_ADDR; - - private String remoteHost = DEFAULT_REMOTE_HOST; - - /** List of locales in descending order */ - private final List<Locale> locales = new LinkedList<Locale>(); - - private boolean secure = false; - - private final ServletContext servletContext; - - private int remotePort = DEFAULT_SERVER_PORT; - - private String localName = DEFAULT_SERVER_NAME; - - private String localAddr = DEFAULT_SERVER_ADDR; - - private int localPort = DEFAULT_SERVER_PORT; - - private Map<String, Part> parts = new HashMap<String, Part>(); - - //--------------------------------------------------------------------- - // HttpServletRequest properties - //--------------------------------------------------------------------- - - private String authType; - - private Cookie[] cookies; - - private final Map<String, HeaderValueHolder> headers = new LinkedCaseInsensitiveMap<HeaderValueHolder>(); - - private String method; - - private String pathInfo; - - private String contextPath = ""; - - private String queryString; - - private String remoteUser; - - private final Set<String> userRoles = new HashSet<String>(); - - private Principal userPrincipal; - - private String requestedSessionId; - - private String requestURI; - - private String servletPath = ""; - - private HttpSession session; - - private boolean requestedSessionIdValid = true; - - private boolean requestedSessionIdFromCookie = true; - - private boolean requestedSessionIdFromURL = false; - - - //--------------------------------------------------------------------- - // Constructors - //--------------------------------------------------------------------- - - /** - * Create a new MockHttpServletRequest with a default - * {@link MockServletContext}. - * @see MockServletContext - */ - public MockHttpServletRequest() { - this(null, "", ""); - } - - /** - * Create a new MockHttpServletRequest with a default - * {@link MockServletContext}. - * @param method the request method (may be <code>null</code>) - * @param requestURI the request URI (may be <code>null</code>) - * @see #setMethod - * @see #setRequestURI - * @see MockServletContext - */ - public MockHttpServletRequest(String method, String requestURI) { - this(null, method, requestURI); - } - - /** - * Create a new MockHttpServletRequest. - * @param servletContext the ServletContext that the request runs in - * (may be <code>null</code> to use a default MockServletContext) - * @see MockServletContext - */ - public MockHttpServletRequest(ServletContext servletContext) { - this(servletContext, "", ""); - } - - /** - * Create a new MockHttpServletRequest. - * @param servletContext the ServletContext that the request runs in - * (may be <code>null</code> to use a default MockServletContext) - * @param method the request method (may be <code>null</code>) - * @param requestURI the request URI (may be <code>null</code>) - * @see #setMethod - * @see #setRequestURI - * @see MockServletContext - */ - public MockHttpServletRequest(ServletContext servletContext, String method, String requestURI) { - this.servletContext = (servletContext != null ? servletContext : new MockServletContext()); - this.method = method; - this.requestURI = requestURI; - this.locales.add(Locale.ENGLISH); - } - - - //--------------------------------------------------------------------- - // Lifecycle methods - //--------------------------------------------------------------------- - - /** - * Return the ServletContext that this request is associated with. - * (Not available in the standard HttpServletRequest interface for some reason.) - */ - public ServletContext getServletContext() { - return this.servletContext; - } - - /** - * Return whether this request is still active (that is, not completed yet). - */ - public boolean isActive() { - return this.active; - } - - /** - * Mark this request as completed, keeping its state. - */ - public void close() { - this.active = false; - } - - /** - * Invalidate this request, clearing its state. - */ - public void invalidate() { - close(); - clearAttributes(); - } - - /** - * Check whether this request is still active (that is, not completed yet), - * throwing an IllegalStateException if not active anymore. - */ - protected void checkActive() throws IllegalStateException { - if (!this.active) { - throw new IllegalStateException("Request is not active anymore"); - } - } - - - //--------------------------------------------------------------------- - // ServletRequest interface - //--------------------------------------------------------------------- - - public Object getAttribute(String name) { - checkActive(); - return this.attributes.get(name); - } - - public Enumeration<String> getAttributeNames() { - checkActive(); - return Collections.enumeration(this.attributes.keySet()); - } - - public String getCharacterEncoding() { - return this.characterEncoding; - } - - public void setCharacterEncoding(String characterEncoding) { - this.characterEncoding = characterEncoding; - updateContentTypeHeader(); - } - - private void updateContentTypeHeader() { - if (this.contentType != null) { - StringBuilder sb = new StringBuilder(this.contentType); - if (this.contentType.toLowerCase().indexOf(CHARSET_PREFIX) == -1 && this.characterEncoding != null) { - sb.append(";").append(CHARSET_PREFIX).append(this.characterEncoding); - } - doAddHeaderValue(CONTENT_TYPE_HEADER, sb.toString(), true); - } - } - - public void setContent(byte[] content) { - this.content = content; - } - - public int getContentLength() { - return (this.content != null ? this.content.length : -1); - } - - public void setContentType(String contentType) { - this.contentType = contentType; - if (contentType != null) { - int charsetIndex = contentType.toLowerCase().indexOf(CHARSET_PREFIX); - if (charsetIndex != -1) { - String encoding = contentType.substring(charsetIndex + CHARSET_PREFIX.length()); - this.characterEncoding = encoding; - } - updateContentTypeHeader(); - } - } - - public String getContentType() { - return this.contentType; - } - - public ServletInputStream getInputStream() { - if (this.content != null) { - return new DelegatingServletInputStream(new ByteArrayInputStream(this.content)); - } - else { - return null; - } - } - - /** - * Set a single value for the specified HTTP parameter. - * <p>If there are already one or more values registered for the given - * parameter name, they will be replaced. - */ - public void setParameter(String name, String value) { - setParameter(name, new String[] {value}); - } - - /** - * Set an array of values for the specified HTTP parameter. - * <p>If there are already one or more values registered for the given - * parameter name, they will be replaced. - */ - public void setParameter(String name, String[] values) { - Assert.notNull(name, "Parameter name must not be null"); - this.parameters.put(name, values); - } - - /** - * Sets all provided parameters <emphasis>replacing</emphasis> any - * existing values for the provided parameter names. To add without - * replacing existing values, use {@link #addParameters(java.util.Map)}. - */ - public void setParameters(Map params) { - Assert.notNull(params, "Parameter map must not be null"); - for (Object key : params.keySet()) { - Assert.isInstanceOf(String.class, key, - "Parameter map key must be of type [" + String.class.getName() + "]"); - Object value = params.get(key); - if (value instanceof String) { - this.setParameter((String) key, (String) value); - } - else if (value instanceof String[]) { - this.setParameter((String) key, (String[]) value); - } - else { - throw new IllegalArgumentException( - "Parameter map value must be single value " + " or array of type [" + String.class.getName() + - "]"); - } - } - } - - /** - * Add a single value for the specified HTTP parameter. - * <p>If there are already one or more values registered for the given - * parameter name, the given value will be added to the end of the list. - */ - public void addParameter(String name, String value) { - addParameter(name, new String[] {value}); - } - - /** - * Add an array of values for the specified HTTP parameter. - * <p>If there are already one or more values registered for the given - * parameter name, the given values will be added to the end of the list. - */ - public void addParameter(String name, String[] values) { - Assert.notNull(name, "Parameter name must not be null"); - String[] oldArr = this.parameters.get(name); - if (oldArr != null) { - String[] newArr = new String[oldArr.length + values.length]; - System.arraycopy(oldArr, 0, newArr, 0, oldArr.length); - System.arraycopy(values, 0, newArr, oldArr.length, values.length); - this.parameters.put(name, newArr); - } - else { - this.parameters.put(name, values); - } - } - - /** - * Adds all provided parameters <emphasis>without</emphasis> replacing - * any existing values. To replace existing values, use - * {@link #setParameters(java.util.Map)}. - */ - public void addParameters(Map params) { - Assert.notNull(params, "Parameter map must not be null"); - for (Object key : params.keySet()) { - Assert.isInstanceOf(String.class, key, - "Parameter map key must be of type [" + String.class.getName() + "]"); - Object value = params.get(key); - if (value instanceof String) { - this.addParameter((String) key, (String) value); - } - else if (value instanceof String[]) { - this.addParameter((String) key, (String[]) value); - } - else { - throw new IllegalArgumentException("Parameter map value must be single value " + - " or array of type [" + String.class.getName() + "]"); - } - } - } - - /** - * Remove already registered values for the specified HTTP parameter, if any. - */ - public void removeParameter(String name) { - Assert.notNull(name, "Parameter name must not be null"); - this.parameters.remove(name); - } - - /** - * Removes all existing parameters. - */ - public void removeAllParameters() { - this.parameters.clear(); - } - - public String getParameter(String name) { - Assert.notNull(name, "Parameter name must not be null"); - String[] arr = this.parameters.get(name); - return (arr != null && arr.length > 0 ? arr[0] : null); - } - - public Enumeration<String> getParameterNames() { - return Collections.enumeration(this.parameters.keySet()); - } - - public String[] getParameterValues(String name) { - Assert.notNull(name, "Parameter name must not be null"); - return this.parameters.get(name); - } - - public Map<String, String[]> getParameterMap() { - return Collections.unmodifiableMap(this.parameters); - } - - public void setProtocol(String protocol) { - this.protocol = protocol; - } - - public String getProtocol() { - return this.protocol; - } - - public void setScheme(String scheme) { - this.scheme = scheme; - } - - public String getScheme() { - return this.scheme; - } - - public void setServerName(String serverName) { - this.serverName = serverName; - } - - public String getServerName() { - return this.serverName; - } - - public void setServerPort(int serverPort) { - this.serverPort = serverPort; - } - - public int getServerPort() { - return this.serverPort; - } - - public BufferedReader getReader() throws UnsupportedEncodingException { - if (this.content != null) { - InputStream sourceStream = new ByteArrayInputStream(this.content); - Reader sourceReader = (this.characterEncoding != null) ? - new InputStreamReader(sourceStream, this.characterEncoding) : new InputStreamReader(sourceStream); - return new BufferedReader(sourceReader); - } - else { - return null; - } - } - - public void setRemoteAddr(String remoteAddr) { - this.remoteAddr = remoteAddr; - } - - public String getRemoteAddr() { - return this.remoteAddr; - } - - public void setRemoteHost(String remoteHost) { - this.remoteHost = remoteHost; - } - - public String getRemoteHost() { - return this.remoteHost; - } - - public void setAttribute(String name, Object value) { - checkActive(); - Assert.notNull(name, "Attribute name must not be null"); - if (value != null) { - this.attributes.put(name, value); - } - else { - this.attributes.remove(name); - } - } - - public void removeAttribute(String name) { - checkActive(); - Assert.notNull(name, "Attribute name must not be null"); - this.attributes.remove(name); - } - - /** - * Clear all of this request's attributes. - */ - public void clearAttributes() { - this.attributes.clear(); - } - - /** - * Add a new preferred locale, before any existing locales. - */ - public void addPreferredLocale(Locale locale) { - Assert.notNull(locale, "Locale must not be null"); - this.locales.add(0, locale); - } - - public Locale getLocale() { - return this.locales.get(0); - } - - public Enumeration<Locale> getLocales() { - return Collections.enumeration(this.locales); - } - - public void setSecure(boolean secure) { - this.secure = secure; - } - - public boolean isSecure() { - return this.secure; - } - - public RequestDispatcher getRequestDispatcher(String path) { - return new MockRequestDispatcher(path); - } - - public String getRealPath(String path) { - return this.servletContext.getRealPath(path); - } - - public void setRemotePort(int remotePort) { - this.remotePort = remotePort; - } - - public int getRemotePort() { - return this.remotePort; - } - - public void setLocalName(String localName) { - this.localName = localName; - } - - public String getLocalName() { - return this.localName; - } - - public void setLocalAddr(String localAddr) { - this.localAddr = localAddr; - } - - public String getLocalAddr() { - return this.localAddr; - } - - public void setLocalPort(int localPort) { - this.localPort = localPort; - } - - public int getLocalPort() { - return this.localPort; - } - - - //--------------------------------------------------------------------- - // HttpServletRequest interface - //--------------------------------------------------------------------- - - public void setAuthType(String authType) { - this.authType = authType; - } - - public String getAuthType() { - return this.authType; - } - - public void setCookies(Cookie... cookies) { - this.cookies = cookies; - } - - public Cookie[] getCookies() { - return this.cookies; - } - - /** - * Add a header entry for the given name. - * <p>If there was no entry for that header name before, - * the value will be used as-is. In case of an existing entry, - * a String array will be created, adding the given value (more - * specifically, its toString representation) as further element. - * <p>Multiple values can only be stored as list of Strings, - * following the Servlet spec (see <code>getHeaders</code> accessor). - * As alternative to repeated <code>addHeader</code> calls for - * individual elements, you can use a single call with an entire - * array or Collection of values as parameter. - * @see #getHeaderNames - * @see #getHeader - * @see #getHeaders - * @see #getDateHeader - * @see #getIntHeader - */ - public void addHeader(String name, Object value) { - if (CONTENT_TYPE_HEADER.equalsIgnoreCase(name)) { - setContentType((String) value); - return; - } - doAddHeaderValue(name, value, false); - } - - @SuppressWarnings("rawtypes") - private void doAddHeaderValue(String name, Object value, boolean replace) { - HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name); - Assert.notNull(value, "Header value must not be null"); - if (header == null || replace) { - header = new HeaderValueHolder(); - this.headers.put(name, header); - } - if (value instanceof Collection) { - header.addValues((Collection) value); - } - else if (value.getClass().isArray()) { - header.addValueArray(value); - } - else { - header.addValue(value); - } - } - - public long getDateHeader(String name) { - HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name); - Object value = (header != null ? header.getValue() : null); - if (value instanceof Date) { - return ((Date) value).getTime(); - } - else if (value instanceof Number) { - return ((Number) value).longValue(); - } - else if (value != null) { - throw new IllegalArgumentException( - "Value for header '" + name + "' is neither a Date nor a Number: " + value); - } - else { - return -1L; - } - } - - public String getHeader(String name) { - HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name); - return (header != null ? header.getValue().toString() : null); - } - - public Enumeration<String> getHeaders(String name) { - HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name); - return Collections.enumeration(header != null ? header.getStringValues() : new LinkedList<String>()); - } - - public Enumeration<String> getHeaderNames() { - return Collections.enumeration(this.headers.keySet()); - } - - public int getIntHeader(String name) { - HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name); - Object value = (header != null ? header.getValue() : null); - if (value instanceof Number) { - return ((Number) value).intValue(); - } - else if (value instanceof String) { - return Integer.parseInt((String) value); - } - else if (value != null) { - throw new NumberFormatException("Value for header '" + name + "' is not a Number: " + value); - } - else { - return -1; - } - } - - public void setMethod(String method) { - this.method = method; - } - - public String getMethod() { - return this.method; - } - - public void setPathInfo(String pathInfo) { - this.pathInfo = pathInfo; - } - - public String getPathInfo() { - return this.pathInfo; - } - - public String getPathTranslated() { - return (this.pathInfo != null ? getRealPath(this.pathInfo) : null); - } - - public void setContextPath(String contextPath) { - this.contextPath = contextPath; - } - - public String getContextPath() { - return this.contextPath; - } - - public void setQueryString(String queryString) { - this.queryString = queryString; - } - - public String getQueryString() { - return this.queryString; - } - - public void setRemoteUser(String remoteUser) { - this.remoteUser = remoteUser; - } - - public String getRemoteUser() { - return this.remoteUser; - } - - public void addUserRole(String role) { - this.userRoles.add(role); - } - - public boolean isUserInRole(String role) { - return this.userRoles.contains(role); - } - - public void setUserPrincipal(Principal userPrincipal) { - this.userPrincipal = userPrincipal; - } - - public Principal getUserPrincipal() { - return this.userPrincipal; - } - - public void setRequestedSessionId(String requestedSessionId) { - this.requestedSessionId = requestedSessionId; - } - - public String getRequestedSessionId() { - return this.requestedSessionId; - } - - public void setRequestURI(String requestURI) { - this.requestURI = requestURI; - } - - public String getRequestURI() { - return this.requestURI; - } - - public StringBuffer getRequestURL() { - StringBuffer url = new StringBuffer(this.scheme); - url.append("://").append(this.serverName).append(':').append(this.serverPort); - url.append(getRequestURI()); - return url; - } - - public void setServletPath(String servletPath) { - this.servletPath = servletPath; - } - - public String getServletPath() { - return this.servletPath; - } - - public void setSession(HttpSession session) { - this.session = session; - if (session instanceof MockHttpSession) { - MockHttpSession mockSession = ((MockHttpSession) session); - mockSession.access(); - } - } - - public HttpSession getSession(boolean create) { - checkActive(); - // Reset session if invalidated. - if (this.session instanceof MockHttpSession && ((MockHttpSession) this.session).isInvalid()) { - this.session = null; - } - // Create new session if necessary. - if (this.session == null && create) { - this.session = new MockHttpSession(this.servletContext); - } - return this.session; - } - - public HttpSession getSession() { - return getSession(true); - } - - public void setRequestedSessionIdValid(boolean requestedSessionIdValid) { - this.requestedSessionIdValid = requestedSessionIdValid; - } - - public boolean isRequestedSessionIdValid() { - return this.requestedSessionIdValid; - } - - public void setRequestedSessionIdFromCookie(boolean requestedSessionIdFromCookie) { - this.requestedSessionIdFromCookie = requestedSessionIdFromCookie; - } - - public boolean isRequestedSessionIdFromCookie() { - return this.requestedSessionIdFromCookie; - } - - public void setRequestedSessionIdFromURL(boolean requestedSessionIdFromURL) { - this.requestedSessionIdFromURL = requestedSessionIdFromURL; - } - - public boolean isRequestedSessionIdFromURL() { - return this.requestedSessionIdFromURL; - } - - public boolean isRequestedSessionIdFromUrl() { - return isRequestedSessionIdFromURL(); - } - - - //--------------------------------------------------------------------- - // Methods introduced in Servlet 3.0 - //--------------------------------------------------------------------- - - public AsyncContext getAsyncContext() { - throw new UnsupportedOperationException(); - } - - public DispatcherType getDispatcherType() { - throw new UnsupportedOperationException(); - } - - public boolean isAsyncSupported() { - throw new UnsupportedOperationException(); - } - - public AsyncContext startAsync() { - throw new UnsupportedOperationException(); - } - - public AsyncContext startAsync(ServletRequest arg0, ServletResponse arg1) { - throw new UnsupportedOperationException(); - } - - public boolean isAsyncStarted() { - throw new UnsupportedOperationException(); - } - - public boolean authenticate(HttpServletResponse arg0) throws IOException, ServletException { - throw new UnsupportedOperationException(); - } - - public void addPart(Part part) { - parts.put(part.getName(), part); - } - - public Part getPart(String key) throws IOException, IllegalStateException, ServletException { - return parts.get(key); - } - - public Collection<Part> getParts() throws IOException, IllegalStateException, ServletException { - return parts.values(); - } - - public void login(String arg0, String arg1) throws ServletException { - throw new UnsupportedOperationException(); - } - - public void logout() throws ServletException { - throw new UnsupportedOperationException(); - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.mock.web; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.UnsupportedEncodingException; +import java.security.Principal; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +import javax.servlet.AsyncContext; +import javax.servlet.DispatcherType; +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletInputStream; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import javax.servlet.http.Part; + +import org.springframework.util.Assert; +import org.springframework.util.LinkedCaseInsensitiveMap; + +/** + * Mock implementation of the {@link javax.servlet.http.HttpServletRequest} + * interface. Supports the Servlet 2.5 API level; throws + * {@link UnsupportedOperationException} for all methods introduced in Servlet 3.0. + * + * <p>Used for testing the web framework; also useful for testing + * application controllers. + * + * @author Juergen Hoeller + * @author Rod Johnson + * @author Rick Evans + * @author Mark Fisher + * @author Chris Beams + * @since 1.0.2 + */ +public class MockHttpServletRequest implements HttpServletRequest { + + /** + * The default protocol: 'http'. + */ + public static final String DEFAULT_PROTOCOL = "http"; + + /** + * The default server address: '127.0.0.1'. + */ + public static final String DEFAULT_SERVER_ADDR = "127.0.0.1"; + + /** + * The default server name: 'localhost'. + */ + public static final String DEFAULT_SERVER_NAME = "localhost"; + + /** + * The default server port: '80'. + */ + public static final int DEFAULT_SERVER_PORT = 80; + + /** + * The default remote address: '127.0.0.1'. + */ + public static final String DEFAULT_REMOTE_ADDR = "127.0.0.1"; + + /** + * The default remote host: 'localhost'. + */ + public static final String DEFAULT_REMOTE_HOST = "localhost"; + + private static final String CONTENT_TYPE_HEADER = "Content-Type"; + + private static final String CHARSET_PREFIX = "charset="; + + + private boolean active = true; + + + //--------------------------------------------------------------------- + // ServletRequest properties + //--------------------------------------------------------------------- + + private final Map<String, Object> attributes = new LinkedHashMap<String, Object>(); + + private String characterEncoding; + + private byte[] content; + + private String contentType; + + private final Map<String, String[]> parameters = new LinkedHashMap<String, String[]>(16); + + private String protocol = DEFAULT_PROTOCOL; + + private String scheme = DEFAULT_PROTOCOL; + + private String serverName = DEFAULT_SERVER_NAME; + + private int serverPort = DEFAULT_SERVER_PORT; + + private String remoteAddr = DEFAULT_REMOTE_ADDR; + + private String remoteHost = DEFAULT_REMOTE_HOST; + + /** List of locales in descending order */ + private final List<Locale> locales = new LinkedList<Locale>(); + + private boolean secure = false; + + private final ServletContext servletContext; + + private int remotePort = DEFAULT_SERVER_PORT; + + private String localName = DEFAULT_SERVER_NAME; + + private String localAddr = DEFAULT_SERVER_ADDR; + + private int localPort = DEFAULT_SERVER_PORT; + + private Map<String, Part> parts = new HashMap<String, Part>(); + + //--------------------------------------------------------------------- + // HttpServletRequest properties + //--------------------------------------------------------------------- + + private String authType; + + private Cookie[] cookies; + + private final Map<String, HeaderValueHolder> headers = new LinkedCaseInsensitiveMap<HeaderValueHolder>(); + + private String method; + + private String pathInfo; + + private String contextPath = ""; + + private String queryString; + + private String remoteUser; + + private final Set<String> userRoles = new HashSet<String>(); + + private Principal userPrincipal; + + private String requestedSessionId; + + private String requestURI; + + private String servletPath = ""; + + private HttpSession session; + + private boolean requestedSessionIdValid = true; + + private boolean requestedSessionIdFromCookie = true; + + private boolean requestedSessionIdFromURL = false; + + + //--------------------------------------------------------------------- + // Constructors + //--------------------------------------------------------------------- + + /** + * Create a new MockHttpServletRequest with a default + * {@link MockServletContext}. + * @see MockServletContext + */ + public MockHttpServletRequest() { + this(null, "", ""); + } + + /** + * Create a new MockHttpServletRequest with a default + * {@link MockServletContext}. + * @param method the request method (may be <code>null</code>) + * @param requestURI the request URI (may be <code>null</code>) + * @see #setMethod + * @see #setRequestURI + * @see MockServletContext + */ + public MockHttpServletRequest(String method, String requestURI) { + this(null, method, requestURI); + } + + /** + * Create a new MockHttpServletRequest. + * @param servletContext the ServletContext that the request runs in + * (may be <code>null</code> to use a default MockServletContext) + * @see MockServletContext + */ + public MockHttpServletRequest(ServletContext servletContext) { + this(servletContext, "", ""); + } + + /** + * Create a new MockHttpServletRequest. + * @param servletContext the ServletContext that the request runs in + * (may be <code>null</code> to use a default MockServletContext) + * @param method the request method (may be <code>null</code>) + * @param requestURI the request URI (may be <code>null</code>) + * @see #setMethod + * @see #setRequestURI + * @see MockServletContext + */ + public MockHttpServletRequest(ServletContext servletContext, String method, String requestURI) { + this.servletContext = (servletContext != null ? servletContext : new MockServletContext()); + this.method = method; + this.requestURI = requestURI; + this.locales.add(Locale.ENGLISH); + } + + + //--------------------------------------------------------------------- + // Lifecycle methods + //--------------------------------------------------------------------- + + /** + * Return the ServletContext that this request is associated with. + * (Not available in the standard HttpServletRequest interface for some reason.) + */ + public ServletContext getServletContext() { + return this.servletContext; + } + + /** + * Return whether this request is still active (that is, not completed yet). + */ + public boolean isActive() { + return this.active; + } + + /** + * Mark this request as completed, keeping its state. + */ + public void close() { + this.active = false; + } + + /** + * Invalidate this request, clearing its state. + */ + public void invalidate() { + close(); + clearAttributes(); + } + + /** + * Check whether this request is still active (that is, not completed yet), + * throwing an IllegalStateException if not active anymore. + */ + protected void checkActive() throws IllegalStateException { + if (!this.active) { + throw new IllegalStateException("Request is not active anymore"); + } + } + + + //--------------------------------------------------------------------- + // ServletRequest interface + //--------------------------------------------------------------------- + + public Object getAttribute(String name) { + checkActive(); + return this.attributes.get(name); + } + + public Enumeration<String> getAttributeNames() { + checkActive(); + return Collections.enumeration(this.attributes.keySet()); + } + + public String getCharacterEncoding() { + return this.characterEncoding; + } + + public void setCharacterEncoding(String characterEncoding) { + this.characterEncoding = characterEncoding; + updateContentTypeHeader(); + } + + private void updateContentTypeHeader() { + if (this.contentType != null) { + StringBuilder sb = new StringBuilder(this.contentType); + if (this.contentType.toLowerCase().indexOf(CHARSET_PREFIX) == -1 && this.characterEncoding != null) { + sb.append(";").append(CHARSET_PREFIX).append(this.characterEncoding); + } + doAddHeaderValue(CONTENT_TYPE_HEADER, sb.toString(), true); + } + } + + public void setContent(byte[] content) { + this.content = content; + } + + public int getContentLength() { + return (this.content != null ? this.content.length : -1); + } + + public void setContentType(String contentType) { + this.contentType = contentType; + if (contentType != null) { + int charsetIndex = contentType.toLowerCase().indexOf(CHARSET_PREFIX); + if (charsetIndex != -1) { + String encoding = contentType.substring(charsetIndex + CHARSET_PREFIX.length()); + this.characterEncoding = encoding; + } + updateContentTypeHeader(); + } + } + + public String getContentType() { + return this.contentType; + } + + public ServletInputStream getInputStream() { + if (this.content != null) { + return new DelegatingServletInputStream(new ByteArrayInputStream(this.content)); + } + else { + return null; + } + } + + /** + * Set a single value for the specified HTTP parameter. + * <p>If there are already one or more values registered for the given + * parameter name, they will be replaced. + */ + public void setParameter(String name, String value) { + setParameter(name, new String[] {value}); + } + + /** + * Set an array of values for the specified HTTP parameter. + * <p>If there are already one or more values registered for the given + * parameter name, they will be replaced. + */ + public void setParameter(String name, String[] values) { + Assert.notNull(name, "Parameter name must not be null"); + this.parameters.put(name, values); + } + + /** + * Sets all provided parameters <emphasis>replacing</emphasis> any + * existing values for the provided parameter names. To add without + * replacing existing values, use {@link #addParameters(java.util.Map)}. + */ + public void setParameters(Map params) { + Assert.notNull(params, "Parameter map must not be null"); + for (Object key : params.keySet()) { + Assert.isInstanceOf(String.class, key, + "Parameter map key must be of type [" + String.class.getName() + "]"); + Object value = params.get(key); + if (value instanceof String) { + this.setParameter((String) key, (String) value); + } + else if (value instanceof String[]) { + this.setParameter((String) key, (String[]) value); + } + else { + throw new IllegalArgumentException( + "Parameter map value must be single value " + " or array of type [" + String.class.getName() + + "]"); + } + } + } + + /** + * Add a single value for the specified HTTP parameter. + * <p>If there are already one or more values registered for the given + * parameter name, the given value will be added to the end of the list. + */ + public void addParameter(String name, String value) { + addParameter(name, new String[] {value}); + } + + /** + * Add an array of values for the specified HTTP parameter. + * <p>If there are already one or more values registered for the given + * parameter name, the given values will be added to the end of the list. + */ + public void addParameter(String name, String[] values) { + Assert.notNull(name, "Parameter name must not be null"); + String[] oldArr = this.parameters.get(name); + if (oldArr != null) { + String[] newArr = new String[oldArr.length + values.length]; + System.arraycopy(oldArr, 0, newArr, 0, oldArr.length); + System.arraycopy(values, 0, newArr, oldArr.length, values.length); + this.parameters.put(name, newArr); + } + else { + this.parameters.put(name, values); + } + } + + /** + * Adds all provided parameters <emphasis>without</emphasis> replacing + * any existing values. To replace existing values, use + * {@link #setParameters(java.util.Map)}. + */ + public void addParameters(Map params) { + Assert.notNull(params, "Parameter map must not be null"); + for (Object key : params.keySet()) { + Assert.isInstanceOf(String.class, key, + "Parameter map key must be of type [" + String.class.getName() + "]"); + Object value = params.get(key); + if (value instanceof String) { + this.addParameter((String) key, (String) value); + } + else if (value instanceof String[]) { + this.addParameter((String) key, (String[]) value); + } + else { + throw new IllegalArgumentException("Parameter map value must be single value " + + " or array of type [" + String.class.getName() + "]"); + } + } + } + + /** + * Remove already registered values for the specified HTTP parameter, if any. + */ + public void removeParameter(String name) { + Assert.notNull(name, "Parameter name must not be null"); + this.parameters.remove(name); + } + + /** + * Removes all existing parameters. + */ + public void removeAllParameters() { + this.parameters.clear(); + } + + public String getParameter(String name) { + Assert.notNull(name, "Parameter name must not be null"); + String[] arr = this.parameters.get(name); + return (arr != null && arr.length > 0 ? arr[0] : null); + } + + public Enumeration<String> getParameterNames() { + return Collections.enumeration(this.parameters.keySet()); + } + + public String[] getParameterValues(String name) { + Assert.notNull(name, "Parameter name must not be null"); + return this.parameters.get(name); + } + + public Map<String, String[]> getParameterMap() { + return Collections.unmodifiableMap(this.parameters); + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + public String getProtocol() { + return this.protocol; + } + + public void setScheme(String scheme) { + this.scheme = scheme; + } + + public String getScheme() { + return this.scheme; + } + + public void setServerName(String serverName) { + this.serverName = serverName; + } + + public String getServerName() { + return this.serverName; + } + + public void setServerPort(int serverPort) { + this.serverPort = serverPort; + } + + public int getServerPort() { + return this.serverPort; + } + + public BufferedReader getReader() throws UnsupportedEncodingException { + if (this.content != null) { + InputStream sourceStream = new ByteArrayInputStream(this.content); + Reader sourceReader = (this.characterEncoding != null) ? + new InputStreamReader(sourceStream, this.characterEncoding) : new InputStreamReader(sourceStream); + return new BufferedReader(sourceReader); + } + else { + return null; + } + } + + public void setRemoteAddr(String remoteAddr) { + this.remoteAddr = remoteAddr; + } + + public String getRemoteAddr() { + return this.remoteAddr; + } + + public void setRemoteHost(String remoteHost) { + this.remoteHost = remoteHost; + } + + public String getRemoteHost() { + return this.remoteHost; + } + + public void setAttribute(String name, Object value) { + checkActive(); + Assert.notNull(name, "Attribute name must not be null"); + if (value != null) { + this.attributes.put(name, value); + } + else { + this.attributes.remove(name); + } + } + + public void removeAttribute(String name) { + checkActive(); + Assert.notNull(name, "Attribute name must not be null"); + this.attributes.remove(name); + } + + /** + * Clear all of this request's attributes. + */ + public void clearAttributes() { + this.attributes.clear(); + } + + /** + * Add a new preferred locale, before any existing locales. + */ + public void addPreferredLocale(Locale locale) { + Assert.notNull(locale, "Locale must not be null"); + this.locales.add(0, locale); + } + + public Locale getLocale() { + return this.locales.get(0); + } + + public Enumeration<Locale> getLocales() { + return Collections.enumeration(this.locales); + } + + public void setSecure(boolean secure) { + this.secure = secure; + } + + public boolean isSecure() { + return this.secure; + } + + public RequestDispatcher getRequestDispatcher(String path) { + return new MockRequestDispatcher(path); + } + + public String getRealPath(String path) { + return this.servletContext.getRealPath(path); + } + + public void setRemotePort(int remotePort) { + this.remotePort = remotePort; + } + + public int getRemotePort() { + return this.remotePort; + } + + public void setLocalName(String localName) { + this.localName = localName; + } + + public String getLocalName() { + return this.localName; + } + + public void setLocalAddr(String localAddr) { + this.localAddr = localAddr; + } + + public String getLocalAddr() { + return this.localAddr; + } + + public void setLocalPort(int localPort) { + this.localPort = localPort; + } + + public int getLocalPort() { + return this.localPort; + } + + + //--------------------------------------------------------------------- + // HttpServletRequest interface + //--------------------------------------------------------------------- + + public void setAuthType(String authType) { + this.authType = authType; + } + + public String getAuthType() { + return this.authType; + } + + public void setCookies(Cookie... cookies) { + this.cookies = cookies; + } + + public Cookie[] getCookies() { + return this.cookies; + } + + /** + * Add a header entry for the given name. + * <p>If there was no entry for that header name before, + * the value will be used as-is. In case of an existing entry, + * a String array will be created, adding the given value (more + * specifically, its toString representation) as further element. + * <p>Multiple values can only be stored as list of Strings, + * following the Servlet spec (see <code>getHeaders</code> accessor). + * As alternative to repeated <code>addHeader</code> calls for + * individual elements, you can use a single call with an entire + * array or Collection of values as parameter. + * @see #getHeaderNames + * @see #getHeader + * @see #getHeaders + * @see #getDateHeader + * @see #getIntHeader + */ + public void addHeader(String name, Object value) { + if (CONTENT_TYPE_HEADER.equalsIgnoreCase(name)) { + setContentType((String) value); + return; + } + doAddHeaderValue(name, value, false); + } + + @SuppressWarnings("rawtypes") + private void doAddHeaderValue(String name, Object value, boolean replace) { + HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name); + Assert.notNull(value, "Header value must not be null"); + if (header == null || replace) { + header = new HeaderValueHolder(); + this.headers.put(name, header); + } + if (value instanceof Collection) { + header.addValues((Collection) value); + } + else if (value.getClass().isArray()) { + header.addValueArray(value); + } + else { + header.addValue(value); + } + } + + public long getDateHeader(String name) { + HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name); + Object value = (header != null ? header.getValue() : null); + if (value instanceof Date) { + return ((Date) value).getTime(); + } + else if (value instanceof Number) { + return ((Number) value).longValue(); + } + else if (value != null) { + throw new IllegalArgumentException( + "Value for header '" + name + "' is neither a Date nor a Number: " + value); + } + else { + return -1L; + } + } + + public String getHeader(String name) { + HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name); + return (header != null ? header.getValue().toString() : null); + } + + public Enumeration<String> getHeaders(String name) { + HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name); + return Collections.enumeration(header != null ? header.getStringValues() : new LinkedList<String>()); + } + + public Enumeration<String> getHeaderNames() { + return Collections.enumeration(this.headers.keySet()); + } + + public int getIntHeader(String name) { + HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name); + Object value = (header != null ? header.getValue() : null); + if (value instanceof Number) { + return ((Number) value).intValue(); + } + else if (value instanceof String) { + return Integer.parseInt((String) value); + } + else if (value != null) { + throw new NumberFormatException("Value for header '" + name + "' is not a Number: " + value); + } + else { + return -1; + } + } + + public void setMethod(String method) { + this.method = method; + } + + public String getMethod() { + return this.method; + } + + public void setPathInfo(String pathInfo) { + this.pathInfo = pathInfo; + } + + public String getPathInfo() { + return this.pathInfo; + } + + public String getPathTranslated() { + return (this.pathInfo != null ? getRealPath(this.pathInfo) : null); + } + + public void setContextPath(String contextPath) { + this.contextPath = contextPath; + } + + public String getContextPath() { + return this.contextPath; + } + + public void setQueryString(String queryString) { + this.queryString = queryString; + } + + public String getQueryString() { + return this.queryString; + } + + public void setRemoteUser(String remoteUser) { + this.remoteUser = remoteUser; + } + + public String getRemoteUser() { + return this.remoteUser; + } + + public void addUserRole(String role) { + this.userRoles.add(role); + } + + public boolean isUserInRole(String role) { + return this.userRoles.contains(role); + } + + public void setUserPrincipal(Principal userPrincipal) { + this.userPrincipal = userPrincipal; + } + + public Principal getUserPrincipal() { + return this.userPrincipal; + } + + public void setRequestedSessionId(String requestedSessionId) { + this.requestedSessionId = requestedSessionId; + } + + public String getRequestedSessionId() { + return this.requestedSessionId; + } + + public void setRequestURI(String requestURI) { + this.requestURI = requestURI; + } + + public String getRequestURI() { + return this.requestURI; + } + + public StringBuffer getRequestURL() { + StringBuffer url = new StringBuffer(this.scheme); + url.append("://").append(this.serverName).append(':').append(this.serverPort); + url.append(getRequestURI()); + return url; + } + + public void setServletPath(String servletPath) { + this.servletPath = servletPath; + } + + public String getServletPath() { + return this.servletPath; + } + + public void setSession(HttpSession session) { + this.session = session; + if (session instanceof MockHttpSession) { + MockHttpSession mockSession = ((MockHttpSession) session); + mockSession.access(); + } + } + + public HttpSession getSession(boolean create) { + checkActive(); + // Reset session if invalidated. + if (this.session instanceof MockHttpSession && ((MockHttpSession) this.session).isInvalid()) { + this.session = null; + } + // Create new session if necessary. + if (this.session == null && create) { + this.session = new MockHttpSession(this.servletContext); + } + return this.session; + } + + public HttpSession getSession() { + return getSession(true); + } + + public void setRequestedSessionIdValid(boolean requestedSessionIdValid) { + this.requestedSessionIdValid = requestedSessionIdValid; + } + + public boolean isRequestedSessionIdValid() { + return this.requestedSessionIdValid; + } + + public void setRequestedSessionIdFromCookie(boolean requestedSessionIdFromCookie) { + this.requestedSessionIdFromCookie = requestedSessionIdFromCookie; + } + + public boolean isRequestedSessionIdFromCookie() { + return this.requestedSessionIdFromCookie; + } + + public void setRequestedSessionIdFromURL(boolean requestedSessionIdFromURL) { + this.requestedSessionIdFromURL = requestedSessionIdFromURL; + } + + public boolean isRequestedSessionIdFromURL() { + return this.requestedSessionIdFromURL; + } + + public boolean isRequestedSessionIdFromUrl() { + return isRequestedSessionIdFromURL(); + } + + + //--------------------------------------------------------------------- + // Methods introduced in Servlet 3.0 + //--------------------------------------------------------------------- + + public AsyncContext getAsyncContext() { + throw new UnsupportedOperationException(); + } + + public DispatcherType getDispatcherType() { + throw new UnsupportedOperationException(); + } + + public boolean isAsyncSupported() { + throw new UnsupportedOperationException(); + } + + public AsyncContext startAsync() { + throw new UnsupportedOperationException(); + } + + public AsyncContext startAsync(ServletRequest arg0, ServletResponse arg1) { + throw new UnsupportedOperationException(); + } + + public boolean isAsyncStarted() { + throw new UnsupportedOperationException(); + } + + public boolean authenticate(HttpServletResponse arg0) throws IOException, ServletException { + throw new UnsupportedOperationException(); + } + + public void addPart(Part part) { + parts.put(part.getName(), part); + } + + public Part getPart(String key) throws IOException, IllegalStateException, ServletException { + return parts.get(key); + } + + public Collection<Part> getParts() throws IOException, IllegalStateException, ServletException { + return parts.values(); + } + + public void login(String arg0, String arg1) throws ServletException { + throw new UnsupportedOperationException(); + } + + public void logout() throws ServletException { + throw new UnsupportedOperationException(); + } + +} diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockHttpSession.java b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockHttpSession.java index 3803e93712d..757414dbbcc 100644 --- a/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockHttpSession.java +++ b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockHttpSession.java @@ -1,246 +1,246 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.mock.web; - -import java.io.Serializable; -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.Map; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpSession; -import javax.servlet.http.HttpSessionBindingEvent; -import javax.servlet.http.HttpSessionBindingListener; -import javax.servlet.http.HttpSessionContext; - -import org.springframework.util.Assert; - -/** - * Mock implementation of the {@link javax.servlet.http.HttpSession} interface. - * Supports the Servlet 2.4 API level. - * - * <p>Used for testing the web framework; also useful for testing - * application controllers. - * - * @author Juergen Hoeller - * @author Rod Johnson - * @author Mark Fisher - * @since 1.0.2 - */ -public class MockHttpSession implements HttpSession { - - public static final String SESSION_COOKIE_NAME = "JSESSION"; - - private static int nextId = 1; - - - private final String id; - - private final long creationTime = System.currentTimeMillis(); - - private int maxInactiveInterval; - - private long lastAccessedTime = System.currentTimeMillis(); - - private final ServletContext servletContext; - - private final Map<String, Object> attributes = new LinkedHashMap<String, Object>(); - - private boolean invalid = false; - - private boolean isNew = true; - - - /** - * Create a new MockHttpSession with a default {@link MockServletContext}. - * @see MockServletContext - */ - public MockHttpSession() { - this(null); - } - - /** - * Create a new MockHttpSession. - * @param servletContext the ServletContext that the session runs in - */ - public MockHttpSession(ServletContext servletContext) { - this(servletContext, null); - } - - /** - * Create a new MockHttpSession. - * @param servletContext the ServletContext that the session runs in - * @param id a unique identifier for this session - */ - public MockHttpSession(ServletContext servletContext, String id) { - this.servletContext = (servletContext != null ? servletContext : new MockServletContext()); - this.id = (id != null ? id : Integer.toString(nextId++)); - } - - - public long getCreationTime() { - return this.creationTime; - } - - public String getId() { - return this.id; - } - - public void access() { - this.lastAccessedTime = System.currentTimeMillis(); - this.isNew = false; - } - - public long getLastAccessedTime() { - return this.lastAccessedTime; - } - - public ServletContext getServletContext() { - return this.servletContext; - } - - public void setMaxInactiveInterval(int interval) { - this.maxInactiveInterval = interval; - } - - public int getMaxInactiveInterval() { - return this.maxInactiveInterval; - } - - public HttpSessionContext getSessionContext() { - throw new UnsupportedOperationException("getSessionContext"); - } - - public Object getAttribute(String name) { - Assert.notNull(name, "Attribute name must not be null"); - return this.attributes.get(name); - } - - public Object getValue(String name) { - return getAttribute(name); - } - - public Enumeration<String> getAttributeNames() { - return Collections.enumeration(this.attributes.keySet()); - } - - public String[] getValueNames() { - return this.attributes.keySet().toArray(new String[this.attributes.size()]); - } - - public void setAttribute(String name, Object value) { - Assert.notNull(name, "Attribute name must not be null"); - if (value != null) { - this.attributes.put(name, value); - if (value instanceof HttpSessionBindingListener) { - ((HttpSessionBindingListener) value).valueBound(new HttpSessionBindingEvent(this, name, value)); - } - } - else { - removeAttribute(name); - } - } - - public void putValue(String name, Object value) { - setAttribute(name, value); - } - - public void removeAttribute(String name) { - Assert.notNull(name, "Attribute name must not be null"); - Object value = this.attributes.remove(name); - if (value instanceof HttpSessionBindingListener) { - ((HttpSessionBindingListener) value).valueUnbound(new HttpSessionBindingEvent(this, name, value)); - } - } - - public void removeValue(String name) { - removeAttribute(name); - } - - /** - * Clear all of this session's attributes. - */ - public void clearAttributes() { - for (Iterator<Map.Entry<String, Object>> it = this.attributes.entrySet().iterator(); it.hasNext();) { - Map.Entry<String, Object> entry = it.next(); - String name = entry.getKey(); - Object value = entry.getValue(); - it.remove(); - if (value instanceof HttpSessionBindingListener) { - ((HttpSessionBindingListener) value).valueUnbound(new HttpSessionBindingEvent(this, name, value)); - } - } - } - - public void invalidate() { - this.invalid = true; - clearAttributes(); - } - - public boolean isInvalid() { - return this.invalid; - } - - public void setNew(boolean value) { - this.isNew = value; - } - - public boolean isNew() { - return this.isNew; - } - - - /** - * Serialize the attributes of this session into an object that can - * be turned into a byte array with standard Java serialization. - * @return a representation of this session's serialized state - */ - public Serializable serializeState() { - HashMap<String, Serializable> state = new HashMap<String, Serializable>(); - for (Iterator<Map.Entry<String, Object>> it = this.attributes.entrySet().iterator(); it.hasNext();) { - Map.Entry<String, Object> entry = it.next(); - String name = entry.getKey(); - Object value = entry.getValue(); - it.remove(); - if (value instanceof Serializable) { - state.put(name, (Serializable) value); - } - else { - // Not serializable... Servlet containers usually automatically - // unbind the attribute in this case. - if (value instanceof HttpSessionBindingListener) { - ((HttpSessionBindingListener) value).valueUnbound(new HttpSessionBindingEvent(this, name, value)); - } - } - } - return state; - } - - /** - * Deserialize the attributes of this session from a state object - * created by {@link #serializeState()}. - * @param state a representation of this session's serialized state - */ - @SuppressWarnings("unchecked") - public void deserializeState(Serializable state) { - Assert.isTrue(state instanceof Map, "Serialized state needs to be of type [java.util.Map]"); - this.attributes.putAll((Map<String, Object>) state); - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.mock.web; + +import java.io.Serializable; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpSession; +import javax.servlet.http.HttpSessionBindingEvent; +import javax.servlet.http.HttpSessionBindingListener; +import javax.servlet.http.HttpSessionContext; + +import org.springframework.util.Assert; + +/** + * Mock implementation of the {@link javax.servlet.http.HttpSession} interface. + * Supports the Servlet 2.4 API level. + * + * <p>Used for testing the web framework; also useful for testing + * application controllers. + * + * @author Juergen Hoeller + * @author Rod Johnson + * @author Mark Fisher + * @since 1.0.2 + */ +public class MockHttpSession implements HttpSession { + + public static final String SESSION_COOKIE_NAME = "JSESSION"; + + private static int nextId = 1; + + + private final String id; + + private final long creationTime = System.currentTimeMillis(); + + private int maxInactiveInterval; + + private long lastAccessedTime = System.currentTimeMillis(); + + private final ServletContext servletContext; + + private final Map<String, Object> attributes = new LinkedHashMap<String, Object>(); + + private boolean invalid = false; + + private boolean isNew = true; + + + /** + * Create a new MockHttpSession with a default {@link MockServletContext}. + * @see MockServletContext + */ + public MockHttpSession() { + this(null); + } + + /** + * Create a new MockHttpSession. + * @param servletContext the ServletContext that the session runs in + */ + public MockHttpSession(ServletContext servletContext) { + this(servletContext, null); + } + + /** + * Create a new MockHttpSession. + * @param servletContext the ServletContext that the session runs in + * @param id a unique identifier for this session + */ + public MockHttpSession(ServletContext servletContext, String id) { + this.servletContext = (servletContext != null ? servletContext : new MockServletContext()); + this.id = (id != null ? id : Integer.toString(nextId++)); + } + + + public long getCreationTime() { + return this.creationTime; + } + + public String getId() { + return this.id; + } + + public void access() { + this.lastAccessedTime = System.currentTimeMillis(); + this.isNew = false; + } + + public long getLastAccessedTime() { + return this.lastAccessedTime; + } + + public ServletContext getServletContext() { + return this.servletContext; + } + + public void setMaxInactiveInterval(int interval) { + this.maxInactiveInterval = interval; + } + + public int getMaxInactiveInterval() { + return this.maxInactiveInterval; + } + + public HttpSessionContext getSessionContext() { + throw new UnsupportedOperationException("getSessionContext"); + } + + public Object getAttribute(String name) { + Assert.notNull(name, "Attribute name must not be null"); + return this.attributes.get(name); + } + + public Object getValue(String name) { + return getAttribute(name); + } + + public Enumeration<String> getAttributeNames() { + return Collections.enumeration(this.attributes.keySet()); + } + + public String[] getValueNames() { + return this.attributes.keySet().toArray(new String[this.attributes.size()]); + } + + public void setAttribute(String name, Object value) { + Assert.notNull(name, "Attribute name must not be null"); + if (value != null) { + this.attributes.put(name, value); + if (value instanceof HttpSessionBindingListener) { + ((HttpSessionBindingListener) value).valueBound(new HttpSessionBindingEvent(this, name, value)); + } + } + else { + removeAttribute(name); + } + } + + public void putValue(String name, Object value) { + setAttribute(name, value); + } + + public void removeAttribute(String name) { + Assert.notNull(name, "Attribute name must not be null"); + Object value = this.attributes.remove(name); + if (value instanceof HttpSessionBindingListener) { + ((HttpSessionBindingListener) value).valueUnbound(new HttpSessionBindingEvent(this, name, value)); + } + } + + public void removeValue(String name) { + removeAttribute(name); + } + + /** + * Clear all of this session's attributes. + */ + public void clearAttributes() { + for (Iterator<Map.Entry<String, Object>> it = this.attributes.entrySet().iterator(); it.hasNext();) { + Map.Entry<String, Object> entry = it.next(); + String name = entry.getKey(); + Object value = entry.getValue(); + it.remove(); + if (value instanceof HttpSessionBindingListener) { + ((HttpSessionBindingListener) value).valueUnbound(new HttpSessionBindingEvent(this, name, value)); + } + } + } + + public void invalidate() { + this.invalid = true; + clearAttributes(); + } + + public boolean isInvalid() { + return this.invalid; + } + + public void setNew(boolean value) { + this.isNew = value; + } + + public boolean isNew() { + return this.isNew; + } + + + /** + * Serialize the attributes of this session into an object that can + * be turned into a byte array with standard Java serialization. + * @return a representation of this session's serialized state + */ + public Serializable serializeState() { + HashMap<String, Serializable> state = new HashMap<String, Serializable>(); + for (Iterator<Map.Entry<String, Object>> it = this.attributes.entrySet().iterator(); it.hasNext();) { + Map.Entry<String, Object> entry = it.next(); + String name = entry.getKey(); + Object value = entry.getValue(); + it.remove(); + if (value instanceof Serializable) { + state.put(name, (Serializable) value); + } + else { + // Not serializable... Servlet containers usually automatically + // unbind the attribute in this case. + if (value instanceof HttpSessionBindingListener) { + ((HttpSessionBindingListener) value).valueUnbound(new HttpSessionBindingEvent(this, name, value)); + } + } + } + return state; + } + + /** + * Deserialize the attributes of this session from a state object + * created by {@link #serializeState()}. + * @param state a representation of this session's serialized state + */ + @SuppressWarnings("unchecked") + public void deserializeState(Serializable state) { + Assert.isTrue(state instanceof Map, "Serialized state needs to be of type [java.util.Map]"); + this.attributes.putAll((Map<String, Object>) state); + } + +} diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockJspWriter.java b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockJspWriter.java index ab47080e756..1d5bf928bf8 100644 --- a/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockJspWriter.java +++ b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockJspWriter.java @@ -1,191 +1,191 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.mock.web; - -import java.io.IOException; -import java.io.PrintWriter; -import java.io.Writer; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.jsp.JspWriter; - -/** - * Mock implementation of the {@link javax.servlet.jsp.JspWriter} class. - * - * <p>Used for testing the web framework; only necessary for testing - * applications when testing custom JSP tags. - * - * @author Juergen Hoeller - * @since 2.5 - */ -public class MockJspWriter extends JspWriter { - - private final HttpServletResponse response; - - private PrintWriter targetWriter; - - - /** - * Create a MockJspWriter for the given response, - * using the response's default Writer. - * @param response the servlet response to wrap - */ - public MockJspWriter(HttpServletResponse response) { - this(response, null); - } - - /** - * Create a MockJspWriter for the given plain Writer. - * @param targetWriter the target Writer to wrap - */ - public MockJspWriter(Writer targetWriter) { - this(null, targetWriter); - } - - /** - * Create a MockJspWriter for the given response. - * @param response the servlet response to wrap - * @param targetWriter the target Writer to wrap - */ - public MockJspWriter(HttpServletResponse response, Writer targetWriter) { - super(DEFAULT_BUFFER, true); - this.response = (response != null ? response : new MockHttpServletResponse()); - if (targetWriter instanceof PrintWriter) { - this.targetWriter = (PrintWriter) targetWriter; - } - else if (targetWriter != null) { - this.targetWriter = new PrintWriter(targetWriter); - } - } - - /** - * Lazily initialize the target Writer. - */ - protected PrintWriter getTargetWriter() throws IOException { - if (this.targetWriter == null) { - this.targetWriter = this.response.getWriter(); - } - return this.targetWriter; - } - - - public void clear() throws IOException { - if (this.response.isCommitted()) { - throw new IOException("Response already committed"); - } - this.response.resetBuffer(); - } - - public void clearBuffer() throws IOException { - } - - public void flush() throws IOException { - this.response.flushBuffer(); - } - - public void close() throws IOException { - flush(); - } - - public int getRemaining() { - return Integer.MAX_VALUE; - } - - public void newLine() throws IOException { - getTargetWriter().println(); - } - - public void write(char value[], int offset, int length) throws IOException { - getTargetWriter().write(value, offset, length); - } - - public void print(boolean value) throws IOException { - getTargetWriter().print(value); - } - - public void print(char value) throws IOException { - getTargetWriter().print(value); - } - - public void print(char[] value) throws IOException { - getTargetWriter().print(value); - } - - public void print(double value) throws IOException { - getTargetWriter().print(value); - } - - public void print(float value) throws IOException { - getTargetWriter().print(value); - } - - public void print(int value) throws IOException { - getTargetWriter().print(value); - } - - public void print(long value) throws IOException { - getTargetWriter().print(value); - } - - public void print(Object value) throws IOException { - getTargetWriter().print(value); - } - - public void print(String value) throws IOException { - getTargetWriter().print(value); - } - - public void println() throws IOException { - getTargetWriter().println(); - } - - public void println(boolean value) throws IOException { - getTargetWriter().println(value); - } - - public void println(char value) throws IOException { - getTargetWriter().println(value); - } - - public void println(char[] value) throws IOException { - getTargetWriter().println(value); - } - - public void println(double value) throws IOException { - getTargetWriter().println(value); - } - - public void println(float value) throws IOException { - getTargetWriter().println(value); - } - - public void println(int value) throws IOException { - getTargetWriter().println(value); - } - - public void println(long value) throws IOException { - getTargetWriter().println(value); - } - - public void println(Object value) throws IOException { - getTargetWriter().println(value); - } - - public void println(String value) throws IOException { - getTargetWriter().println(value); - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.mock.web; + +import java.io.IOException; +import java.io.PrintWriter; +import java.io.Writer; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.jsp.JspWriter; + +/** + * Mock implementation of the {@link javax.servlet.jsp.JspWriter} class. + * + * <p>Used for testing the web framework; only necessary for testing + * applications when testing custom JSP tags. + * + * @author Juergen Hoeller + * @since 2.5 + */ +public class MockJspWriter extends JspWriter { + + private final HttpServletResponse response; + + private PrintWriter targetWriter; + + + /** + * Create a MockJspWriter for the given response, + * using the response's default Writer. + * @param response the servlet response to wrap + */ + public MockJspWriter(HttpServletResponse response) { + this(response, null); + } + + /** + * Create a MockJspWriter for the given plain Writer. + * @param targetWriter the target Writer to wrap + */ + public MockJspWriter(Writer targetWriter) { + this(null, targetWriter); + } + + /** + * Create a MockJspWriter for the given response. + * @param response the servlet response to wrap + * @param targetWriter the target Writer to wrap + */ + public MockJspWriter(HttpServletResponse response, Writer targetWriter) { + super(DEFAULT_BUFFER, true); + this.response = (response != null ? response : new MockHttpServletResponse()); + if (targetWriter instanceof PrintWriter) { + this.targetWriter = (PrintWriter) targetWriter; + } + else if (targetWriter != null) { + this.targetWriter = new PrintWriter(targetWriter); + } + } + + /** + * Lazily initialize the target Writer. + */ + protected PrintWriter getTargetWriter() throws IOException { + if (this.targetWriter == null) { + this.targetWriter = this.response.getWriter(); + } + return this.targetWriter; + } + + + public void clear() throws IOException { + if (this.response.isCommitted()) { + throw new IOException("Response already committed"); + } + this.response.resetBuffer(); + } + + public void clearBuffer() throws IOException { + } + + public void flush() throws IOException { + this.response.flushBuffer(); + } + + public void close() throws IOException { + flush(); + } + + public int getRemaining() { + return Integer.MAX_VALUE; + } + + public void newLine() throws IOException { + getTargetWriter().println(); + } + + public void write(char value[], int offset, int length) throws IOException { + getTargetWriter().write(value, offset, length); + } + + public void print(boolean value) throws IOException { + getTargetWriter().print(value); + } + + public void print(char value) throws IOException { + getTargetWriter().print(value); + } + + public void print(char[] value) throws IOException { + getTargetWriter().print(value); + } + + public void print(double value) throws IOException { + getTargetWriter().print(value); + } + + public void print(float value) throws IOException { + getTargetWriter().print(value); + } + + public void print(int value) throws IOException { + getTargetWriter().print(value); + } + + public void print(long value) throws IOException { + getTargetWriter().print(value); + } + + public void print(Object value) throws IOException { + getTargetWriter().print(value); + } + + public void print(String value) throws IOException { + getTargetWriter().print(value); + } + + public void println() throws IOException { + getTargetWriter().println(); + } + + public void println(boolean value) throws IOException { + getTargetWriter().println(value); + } + + public void println(char value) throws IOException { + getTargetWriter().println(value); + } + + public void println(char[] value) throws IOException { + getTargetWriter().println(value); + } + + public void println(double value) throws IOException { + getTargetWriter().println(value); + } + + public void println(float value) throws IOException { + getTargetWriter().println(value); + } + + public void println(int value) throws IOException { + getTargetWriter().println(value); + } + + public void println(long value) throws IOException { + getTargetWriter().println(value); + } + + public void println(Object value) throws IOException { + getTargetWriter().println(value); + } + + public void println(String value) throws IOException { + getTargetWriter().println(value); + } + +} diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockMultipartFile.java b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockMultipartFile.java index e91936de863..24518968c38 100644 --- a/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockMultipartFile.java +++ b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockMultipartFile.java @@ -1,134 +1,134 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.mock.web; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.Collections; -import java.util.Iterator; - -import org.springframework.util.Assert; -import org.springframework.util.FileCopyUtils; -import org.springframework.web.multipart.MultipartFile; - -/** - * Mock implementation of the {@link org.springframework.web.multipart.MultipartFile} - * interface. - * - * <p>Useful in conjunction with a {@link MockMultipartHttpServletRequest} - * for testing application controllers that access multipart uploads. - * - * @author Juergen Hoeller - * @author Eric Crampton - * @since 2.0 - * @see MockMultipartHttpServletRequest - */ -public class MockMultipartFile implements MultipartFile { - - private final String name; - - private String originalFilename; - - private String contentType; - - private final byte[] content; - - - /** - * Create a new MockMultipartFile with the given content. - * @param name the name of the file - * @param content the content of the file - */ - public MockMultipartFile(String name, byte[] content) { - this(name, "", null, content); - } - - /** - * Create a new MockMultipartFile with the given content. - * @param name the name of the file - * @param contentStream the content of the file as stream - * @throws IOException if reading from the stream failed - */ - public MockMultipartFile(String name, InputStream contentStream) throws IOException { - this(name, "", null, FileCopyUtils.copyToByteArray(contentStream)); - } - - /** - * Create a new MockMultipartFile with the given content. - * @param name the name of the file - * @param originalFilename the original filename (as on the client's machine) - * @param contentType the content type (if known) - * @param content the content of the file - */ - public MockMultipartFile(String name, String originalFilename, String contentType, byte[] content) { - Assert.hasLength(name, "Name must not be null"); - this.name = name; - this.originalFilename = (originalFilename != null ? originalFilename : ""); - this.contentType = contentType; - this.content = (content != null ? content : new byte[0]); - } - - /** - * Create a new MockMultipartFile with the given content. - * @param name the name of the file - * @param originalFilename the original filename (as on the client's machine) - * @param contentType the content type (if known) - * @param contentStream the content of the file as stream - * @throws IOException if reading from the stream failed - */ - public MockMultipartFile(String name, String originalFilename, String contentType, InputStream contentStream) - throws IOException { - - this(name, originalFilename, contentType, FileCopyUtils.copyToByteArray(contentStream)); - } - - - public String getName() { - return this.name; - } - - public String getOriginalFilename() { - return this.originalFilename; - } - - public String getContentType() { - return this.contentType; - } - - public boolean isEmpty() { - return (this.content.length == 0); - } - - public long getSize() { - return this.content.length; - } - - public byte[] getBytes() throws IOException { - return this.content; - } - - public InputStream getInputStream() throws IOException { - return new ByteArrayInputStream(this.content); - } - - public void transferTo(File dest) throws IOException, IllegalStateException { - FileCopyUtils.copy(this.content, dest); - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.mock.web; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.Collections; +import java.util.Iterator; + +import org.springframework.util.Assert; +import org.springframework.util.FileCopyUtils; +import org.springframework.web.multipart.MultipartFile; + +/** + * Mock implementation of the {@link org.springframework.web.multipart.MultipartFile} + * interface. + * + * <p>Useful in conjunction with a {@link MockMultipartHttpServletRequest} + * for testing application controllers that access multipart uploads. + * + * @author Juergen Hoeller + * @author Eric Crampton + * @since 2.0 + * @see MockMultipartHttpServletRequest + */ +public class MockMultipartFile implements MultipartFile { + + private final String name; + + private String originalFilename; + + private String contentType; + + private final byte[] content; + + + /** + * Create a new MockMultipartFile with the given content. + * @param name the name of the file + * @param content the content of the file + */ + public MockMultipartFile(String name, byte[] content) { + this(name, "", null, content); + } + + /** + * Create a new MockMultipartFile with the given content. + * @param name the name of the file + * @param contentStream the content of the file as stream + * @throws IOException if reading from the stream failed + */ + public MockMultipartFile(String name, InputStream contentStream) throws IOException { + this(name, "", null, FileCopyUtils.copyToByteArray(contentStream)); + } + + /** + * Create a new MockMultipartFile with the given content. + * @param name the name of the file + * @param originalFilename the original filename (as on the client's machine) + * @param contentType the content type (if known) + * @param content the content of the file + */ + public MockMultipartFile(String name, String originalFilename, String contentType, byte[] content) { + Assert.hasLength(name, "Name must not be null"); + this.name = name; + this.originalFilename = (originalFilename != null ? originalFilename : ""); + this.contentType = contentType; + this.content = (content != null ? content : new byte[0]); + } + + /** + * Create a new MockMultipartFile with the given content. + * @param name the name of the file + * @param originalFilename the original filename (as on the client's machine) + * @param contentType the content type (if known) + * @param contentStream the content of the file as stream + * @throws IOException if reading from the stream failed + */ + public MockMultipartFile(String name, String originalFilename, String contentType, InputStream contentStream) + throws IOException { + + this(name, originalFilename, contentType, FileCopyUtils.copyToByteArray(contentStream)); + } + + + public String getName() { + return this.name; + } + + public String getOriginalFilename() { + return this.originalFilename; + } + + public String getContentType() { + return this.contentType; + } + + public boolean isEmpty() { + return (this.content.length == 0); + } + + public long getSize() { + return this.content.length; + } + + public byte[] getBytes() throws IOException { + return this.content; + } + + public InputStream getInputStream() throws IOException { + return new ByteArrayInputStream(this.content); + } + + public void transferTo(File dest) throws IOException, IllegalStateException { + FileCopyUtils.copy(this.content, dest); + } + +} diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockMultipartHttpServletRequest.java b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockMultipartHttpServletRequest.java index e8720dfa0ac..b01c4fdcf84 100644 --- a/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockMultipartHttpServletRequest.java +++ b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockMultipartHttpServletRequest.java @@ -1,131 +1,131 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.mock.web; - -import java.util.Collections; -import java.util.Enumeration; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.util.Assert; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.web.multipart.MultipartFile; -import org.springframework.web.multipart.MultipartHttpServletRequest; - -/** - * Mock implementation of the - * {@link org.springframework.web.multipart.MultipartHttpServletRequest} interface. - * - * <p>Useful for testing application controllers that access multipart uploads. - * The {@link MockMultipartFile} can be used to populate these mock requests - * with files. - * - * @author Juergen Hoeller - * @author Eric Crampton - * @author Arjen Poutsma - * @since 2.0 - * @see MockMultipartFile - */ -public class MockMultipartHttpServletRequest extends MockHttpServletRequest implements MultipartHttpServletRequest { - - private final MultiValueMap<String, MultipartFile> multipartFiles = - new LinkedMultiValueMap<String, MultipartFile>(); - - - public MockMultipartHttpServletRequest() { - setMethod("POST"); - setContentType("multipart/form-data"); - } - - - /** - * Add a file to this request. The parameter name from the multipart - * form is taken from the {@link MultipartFile#getName()}. - * @param file multipart file to be added - */ - public void addFile(MultipartFile file) { - Assert.notNull(file, "MultipartFile must not be null"); - this.multipartFiles.add(file.getName(), file); - } - - public Iterator<String> getFileNames() { - return this.multipartFiles.keySet().iterator(); - } - - public MultipartFile getFile(String name) { - return this.multipartFiles.getFirst(name); - } - - public List<MultipartFile> getFiles(String name) { - List<MultipartFile> multipartFiles = this.multipartFiles.get(name); - if (multipartFiles != null) { - return multipartFiles; - } - else { - return Collections.emptyList(); - } - } - - public Map<String, MultipartFile> getFileMap() { - return this.multipartFiles.toSingleValueMap(); - } - - public MultiValueMap<String, MultipartFile> getMultiFileMap() { - return new LinkedMultiValueMap<String, MultipartFile>(this.multipartFiles); - } - - public String getMultipartContentType(String paramOrFileName) { - MultipartFile file = getFile(paramOrFileName); - if (file != null) { - return file.getContentType(); - } - else { - return null; - } - } - - public HttpMethod getRequestMethod() { - return HttpMethod.valueOf(getMethod()); - } - - public HttpHeaders getRequestHeaders() { - HttpHeaders headers = new HttpHeaders(); - Enumeration<String> headerNames = getHeaderNames(); - while (headerNames.hasMoreElements()) { - String headerName = headerNames.nextElement(); - headers.put(headerName, Collections.list(getHeaders(headerName))); - } - return headers; - } - - public HttpHeaders getMultipartHeaders(String paramOrFileName) { - String contentType = getMultipartContentType(paramOrFileName); - if (contentType != null) { - HttpHeaders headers = new HttpHeaders(); - headers.add("Content-Type", contentType); - return headers; - } - else { - return null; - } - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.mock.web; + +import java.util.Collections; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.util.Assert; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.MultipartHttpServletRequest; + +/** + * Mock implementation of the + * {@link org.springframework.web.multipart.MultipartHttpServletRequest} interface. + * + * <p>Useful for testing application controllers that access multipart uploads. + * The {@link MockMultipartFile} can be used to populate these mock requests + * with files. + * + * @author Juergen Hoeller + * @author Eric Crampton + * @author Arjen Poutsma + * @since 2.0 + * @see MockMultipartFile + */ +public class MockMultipartHttpServletRequest extends MockHttpServletRequest implements MultipartHttpServletRequest { + + private final MultiValueMap<String, MultipartFile> multipartFiles = + new LinkedMultiValueMap<String, MultipartFile>(); + + + public MockMultipartHttpServletRequest() { + setMethod("POST"); + setContentType("multipart/form-data"); + } + + + /** + * Add a file to this request. The parameter name from the multipart + * form is taken from the {@link MultipartFile#getName()}. + * @param file multipart file to be added + */ + public void addFile(MultipartFile file) { + Assert.notNull(file, "MultipartFile must not be null"); + this.multipartFiles.add(file.getName(), file); + } + + public Iterator<String> getFileNames() { + return this.multipartFiles.keySet().iterator(); + } + + public MultipartFile getFile(String name) { + return this.multipartFiles.getFirst(name); + } + + public List<MultipartFile> getFiles(String name) { + List<MultipartFile> multipartFiles = this.multipartFiles.get(name); + if (multipartFiles != null) { + return multipartFiles; + } + else { + return Collections.emptyList(); + } + } + + public Map<String, MultipartFile> getFileMap() { + return this.multipartFiles.toSingleValueMap(); + } + + public MultiValueMap<String, MultipartFile> getMultiFileMap() { + return new LinkedMultiValueMap<String, MultipartFile>(this.multipartFiles); + } + + public String getMultipartContentType(String paramOrFileName) { + MultipartFile file = getFile(paramOrFileName); + if (file != null) { + return file.getContentType(); + } + else { + return null; + } + } + + public HttpMethod getRequestMethod() { + return HttpMethod.valueOf(getMethod()); + } + + public HttpHeaders getRequestHeaders() { + HttpHeaders headers = new HttpHeaders(); + Enumeration<String> headerNames = getHeaderNames(); + while (headerNames.hasMoreElements()) { + String headerName = headerNames.nextElement(); + headers.put(headerName, Collections.list(getHeaders(headerName))); + } + return headers; + } + + public HttpHeaders getMultipartHeaders(String paramOrFileName) { + String contentType = getMultipartContentType(paramOrFileName); + if (contentType != null) { + HttpHeaders headers = new HttpHeaders(); + headers.add("Content-Type", contentType); + return headers; + } + else { + return null; + } + } + +} diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockPageContext.java b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockPageContext.java index 919b50fe41d..f0f2433efc7 100644 --- a/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockPageContext.java +++ b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockPageContext.java @@ -1,370 +1,370 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.mock.web; - -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.util.Collections; -import java.util.Enumeration; -import java.util.LinkedHashMap; -import java.util.Map; -import javax.el.ELContext; -import javax.servlet.Servlet; -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; -import javax.servlet.jsp.JspWriter; -import javax.servlet.jsp.PageContext; -import javax.servlet.jsp.el.ELException; -import javax.servlet.jsp.el.Expression; -import javax.servlet.jsp.el.ExpressionEvaluator; -import javax.servlet.jsp.el.FunctionMapper; -import javax.servlet.jsp.el.VariableResolver; - -import org.springframework.util.Assert; - -/** - * Mock implementation of the {@link javax.servlet.jsp.PageContext} interface. - * - * <p>Used for testing the web framework; only necessary for testing - * applications when testing custom JSP tags. - * - * <p>Note: Expects initialization via the constructor rather than via the - * <code>PageContext.initialize</code> method. Does not support writing to - * a JspWriter, request dispatching, and <code>handlePageException</code> calls. - * - * @author Juergen Hoeller - * @since 1.0.2 - */ -public class MockPageContext extends PageContext { - - private final ServletContext servletContext; - - private final HttpServletRequest request; - - private final HttpServletResponse response; - - private final ServletConfig servletConfig; - - private final Map<String, Object> attributes = new LinkedHashMap<String, Object>(); - - private JspWriter out; - - - /** - * Create new MockPageContext with a default {@link MockServletContext}, - * {@link MockHttpServletRequest}, {@link MockHttpServletResponse}, - * {@link MockServletConfig}. - */ - public MockPageContext() { - this(null, null, null, null); - } - - /** - * Create new MockPageContext with a default {@link MockHttpServletRequest}, - * {@link MockHttpServletResponse}, {@link MockServletConfig}. - * @param servletContext the ServletContext that the JSP page runs in - * (only necessary when actually accessing the ServletContext) - */ - public MockPageContext(ServletContext servletContext) { - this(servletContext, null, null, null); - } - - /** - * Create new MockPageContext with a MockHttpServletResponse, - * MockServletConfig. - * @param servletContext the ServletContext that the JSP page runs in - * @param request the current HttpServletRequest - * (only necessary when actually accessing the request) - */ - public MockPageContext(ServletContext servletContext, HttpServletRequest request) { - this(servletContext, request, null, null); - } - - /** - * Create new MockPageContext with a MockServletConfig. - * @param servletContext the ServletContext that the JSP page runs in - * @param request the current HttpServletRequest - * @param response the current HttpServletResponse - * (only necessary when actually writing to the response) - */ - public MockPageContext(ServletContext servletContext, HttpServletRequest request, HttpServletResponse response) { - this(servletContext, request, response, null); - } - - /** - * Create new MockServletConfig. - * @param servletContext the ServletContext that the JSP page runs in - * @param request the current HttpServletRequest - * @param response the current HttpServletResponse - * @param servletConfig the ServletConfig (hardly ever accessed from within a tag) - */ - public MockPageContext(ServletContext servletContext, HttpServletRequest request, - HttpServletResponse response, ServletConfig servletConfig) { - - this.servletContext = (servletContext != null ? servletContext : new MockServletContext()); - this.request = (request != null ? request : new MockHttpServletRequest(servletContext)); - this.response = (response != null ? response : new MockHttpServletResponse()); - this.servletConfig = (servletConfig != null ? servletConfig : new MockServletConfig(servletContext)); - } - - - public void initialize( - Servlet servlet, ServletRequest request, ServletResponse response, - String errorPageURL, boolean needsSession, int bufferSize, boolean autoFlush) { - - throw new UnsupportedOperationException("Use appropriate constructor"); - } - - public void release() { - } - - public void setAttribute(String name, Object value) { - Assert.notNull(name, "Attribute name must not be null"); - if (value != null) { - this.attributes.put(name, value); - } - else { - this.attributes.remove(name); - } - } - - public void setAttribute(String name, Object value, int scope) { - Assert.notNull(name, "Attribute name must not be null"); - switch (scope) { - case PAGE_SCOPE: - setAttribute(name, value); - break; - case REQUEST_SCOPE: - this.request.setAttribute(name, value); - break; - case SESSION_SCOPE: - this.request.getSession().setAttribute(name, value); - break; - case APPLICATION_SCOPE: - this.servletContext.setAttribute(name, value); - break; - default: - throw new IllegalArgumentException("Invalid scope: " + scope); - } - } - - public Object getAttribute(String name) { - Assert.notNull(name, "Attribute name must not be null"); - return this.attributes.get(name); - } - - public Object getAttribute(String name, int scope) { - Assert.notNull(name, "Attribute name must not be null"); - switch (scope) { - case PAGE_SCOPE: - return getAttribute(name); - case REQUEST_SCOPE: - return this.request.getAttribute(name); - case SESSION_SCOPE: - HttpSession session = this.request.getSession(false); - return (session != null ? session.getAttribute(name) : null); - case APPLICATION_SCOPE: - return this.servletContext.getAttribute(name); - default: - throw new IllegalArgumentException("Invalid scope: " + scope); - } - } - - public Object findAttribute(String name) { - Object value = getAttribute(name); - if (value == null) { - value = getAttribute(name, REQUEST_SCOPE); - if (value == null) { - value = getAttribute(name, SESSION_SCOPE); - if (value == null) { - value = getAttribute(name, APPLICATION_SCOPE); - } - } - } - return value; - } - - public void removeAttribute(String name) { - Assert.notNull(name, "Attribute name must not be null"); - this.removeAttribute(name, PageContext.PAGE_SCOPE); - this.removeAttribute(name, PageContext.REQUEST_SCOPE); - this.removeAttribute(name, PageContext.SESSION_SCOPE); - this.removeAttribute(name, PageContext.APPLICATION_SCOPE); - } - - public void removeAttribute(String name, int scope) { - Assert.notNull(name, "Attribute name must not be null"); - switch (scope) { - case PAGE_SCOPE: - this.attributes.remove(name); - break; - case REQUEST_SCOPE: - this.request.removeAttribute(name); - break; - case SESSION_SCOPE: - this.request.getSession().removeAttribute(name); - break; - case APPLICATION_SCOPE: - this.servletContext.removeAttribute(name); - break; - default: - throw new IllegalArgumentException("Invalid scope: " + scope); - } - } - - public int getAttributesScope(String name) { - if (getAttribute(name) != null) { - return PAGE_SCOPE; - } - else if (getAttribute(name, REQUEST_SCOPE) != null) { - return REQUEST_SCOPE; - } - else if (getAttribute(name, SESSION_SCOPE) != null) { - return SESSION_SCOPE; - } - else if (getAttribute(name, APPLICATION_SCOPE) != null) { - return APPLICATION_SCOPE; - } - else { - return 0; - } - } - - public Enumeration<String> getAttributeNames() { - return Collections.enumeration(this.attributes.keySet()); - } - - @SuppressWarnings("unchecked") - public Enumeration<String> getAttributeNamesInScope(int scope) { - switch (scope) { - case PAGE_SCOPE: - return getAttributeNames(); - case REQUEST_SCOPE: - return this.request.getAttributeNames(); - case SESSION_SCOPE: - HttpSession session = this.request.getSession(false); - return (session != null ? session.getAttributeNames() : null); - case APPLICATION_SCOPE: - return this.servletContext.getAttributeNames(); - default: - throw new IllegalArgumentException("Invalid scope: " + scope); - } - } - - public JspWriter getOut() { - if (this.out == null) { - this.out = new MockJspWriter(this.response); - } - return this.out; - } - - public ExpressionEvaluator getExpressionEvaluator() { - return new ExpressionEvaluator() { - public Expression parseExpression(String expression, Class expectedType, FunctionMapper fMapper) throws ELException { - throw new UnsupportedOperationException(); - } - public Object evaluate(String expression, Class expectedType, VariableResolver vResolver, FunctionMapper fMapper) throws ELException { - String key = expression.substring(2, expression.length() - 1); - return findAttribute(key); - } - }; - } - - public ELContext getELContext() { - return null; - } - - public VariableResolver getVariableResolver() { - return new VariableResolver() { - public Object resolveVariable(String pName) throws ELException { - if (pName.equals("pageContext")) { - return this; - } else { - return null; - } - } - }; - } - - public HttpSession getSession() { - return this.request.getSession(); - } - - public Object getPage() { - return this; - } - - public ServletRequest getRequest() { - return this.request; - } - - public ServletResponse getResponse() { - return this.response; - } - - public Exception getException() { - return null; - } - - public ServletConfig getServletConfig() { - return this.servletConfig; - } - - public ServletContext getServletContext() { - return this.servletContext; - } - - public void forward(String path) throws ServletException, IOException { - this.request.getRequestDispatcher(path).forward(this.request, this.response); - } - - public void include(String path) throws ServletException, IOException { - this.request.getRequestDispatcher(path).include(this.request, this.response); - } - - public void include(String path, boolean flush) throws ServletException, IOException { - this.request.getRequestDispatcher(path).include(this.request, this.response); - if (flush) { - this.response.flushBuffer(); - } - } - - public byte[] getContentAsByteArray() { - Assert.isTrue(this.response instanceof MockHttpServletResponse); - return ((MockHttpServletResponse) this.response).getContentAsByteArray(); - } - - public String getContentAsString() throws UnsupportedEncodingException { - Assert.isTrue(this.response instanceof MockHttpServletResponse); - return ((MockHttpServletResponse) this.response).getContentAsString(); - } - - public void handlePageException(Exception ex) throws ServletException, IOException { - throw new ServletException("Page exception", ex); - } - - public void handlePageException(Throwable ex) throws ServletException, IOException { - throw new ServletException("Page exception", ex); - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.mock.web; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.util.Collections; +import java.util.Enumeration; +import java.util.LinkedHashMap; +import java.util.Map; +import javax.el.ELContext; +import javax.servlet.Servlet; +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import javax.servlet.jsp.JspWriter; +import javax.servlet.jsp.PageContext; +import javax.servlet.jsp.el.ELException; +import javax.servlet.jsp.el.Expression; +import javax.servlet.jsp.el.ExpressionEvaluator; +import javax.servlet.jsp.el.FunctionMapper; +import javax.servlet.jsp.el.VariableResolver; + +import org.springframework.util.Assert; + +/** + * Mock implementation of the {@link javax.servlet.jsp.PageContext} interface. + * + * <p>Used for testing the web framework; only necessary for testing + * applications when testing custom JSP tags. + * + * <p>Note: Expects initialization via the constructor rather than via the + * <code>PageContext.initialize</code> method. Does not support writing to + * a JspWriter, request dispatching, and <code>handlePageException</code> calls. + * + * @author Juergen Hoeller + * @since 1.0.2 + */ +public class MockPageContext extends PageContext { + + private final ServletContext servletContext; + + private final HttpServletRequest request; + + private final HttpServletResponse response; + + private final ServletConfig servletConfig; + + private final Map<String, Object> attributes = new LinkedHashMap<String, Object>(); + + private JspWriter out; + + + /** + * Create new MockPageContext with a default {@link MockServletContext}, + * {@link MockHttpServletRequest}, {@link MockHttpServletResponse}, + * {@link MockServletConfig}. + */ + public MockPageContext() { + this(null, null, null, null); + } + + /** + * Create new MockPageContext with a default {@link MockHttpServletRequest}, + * {@link MockHttpServletResponse}, {@link MockServletConfig}. + * @param servletContext the ServletContext that the JSP page runs in + * (only necessary when actually accessing the ServletContext) + */ + public MockPageContext(ServletContext servletContext) { + this(servletContext, null, null, null); + } + + /** + * Create new MockPageContext with a MockHttpServletResponse, + * MockServletConfig. + * @param servletContext the ServletContext that the JSP page runs in + * @param request the current HttpServletRequest + * (only necessary when actually accessing the request) + */ + public MockPageContext(ServletContext servletContext, HttpServletRequest request) { + this(servletContext, request, null, null); + } + + /** + * Create new MockPageContext with a MockServletConfig. + * @param servletContext the ServletContext that the JSP page runs in + * @param request the current HttpServletRequest + * @param response the current HttpServletResponse + * (only necessary when actually writing to the response) + */ + public MockPageContext(ServletContext servletContext, HttpServletRequest request, HttpServletResponse response) { + this(servletContext, request, response, null); + } + + /** + * Create new MockServletConfig. + * @param servletContext the ServletContext that the JSP page runs in + * @param request the current HttpServletRequest + * @param response the current HttpServletResponse + * @param servletConfig the ServletConfig (hardly ever accessed from within a tag) + */ + public MockPageContext(ServletContext servletContext, HttpServletRequest request, + HttpServletResponse response, ServletConfig servletConfig) { + + this.servletContext = (servletContext != null ? servletContext : new MockServletContext()); + this.request = (request != null ? request : new MockHttpServletRequest(servletContext)); + this.response = (response != null ? response : new MockHttpServletResponse()); + this.servletConfig = (servletConfig != null ? servletConfig : new MockServletConfig(servletContext)); + } + + + public void initialize( + Servlet servlet, ServletRequest request, ServletResponse response, + String errorPageURL, boolean needsSession, int bufferSize, boolean autoFlush) { + + throw new UnsupportedOperationException("Use appropriate constructor"); + } + + public void release() { + } + + public void setAttribute(String name, Object value) { + Assert.notNull(name, "Attribute name must not be null"); + if (value != null) { + this.attributes.put(name, value); + } + else { + this.attributes.remove(name); + } + } + + public void setAttribute(String name, Object value, int scope) { + Assert.notNull(name, "Attribute name must not be null"); + switch (scope) { + case PAGE_SCOPE: + setAttribute(name, value); + break; + case REQUEST_SCOPE: + this.request.setAttribute(name, value); + break; + case SESSION_SCOPE: + this.request.getSession().setAttribute(name, value); + break; + case APPLICATION_SCOPE: + this.servletContext.setAttribute(name, value); + break; + default: + throw new IllegalArgumentException("Invalid scope: " + scope); + } + } + + public Object getAttribute(String name) { + Assert.notNull(name, "Attribute name must not be null"); + return this.attributes.get(name); + } + + public Object getAttribute(String name, int scope) { + Assert.notNull(name, "Attribute name must not be null"); + switch (scope) { + case PAGE_SCOPE: + return getAttribute(name); + case REQUEST_SCOPE: + return this.request.getAttribute(name); + case SESSION_SCOPE: + HttpSession session = this.request.getSession(false); + return (session != null ? session.getAttribute(name) : null); + case APPLICATION_SCOPE: + return this.servletContext.getAttribute(name); + default: + throw new IllegalArgumentException("Invalid scope: " + scope); + } + } + + public Object findAttribute(String name) { + Object value = getAttribute(name); + if (value == null) { + value = getAttribute(name, REQUEST_SCOPE); + if (value == null) { + value = getAttribute(name, SESSION_SCOPE); + if (value == null) { + value = getAttribute(name, APPLICATION_SCOPE); + } + } + } + return value; + } + + public void removeAttribute(String name) { + Assert.notNull(name, "Attribute name must not be null"); + this.removeAttribute(name, PageContext.PAGE_SCOPE); + this.removeAttribute(name, PageContext.REQUEST_SCOPE); + this.removeAttribute(name, PageContext.SESSION_SCOPE); + this.removeAttribute(name, PageContext.APPLICATION_SCOPE); + } + + public void removeAttribute(String name, int scope) { + Assert.notNull(name, "Attribute name must not be null"); + switch (scope) { + case PAGE_SCOPE: + this.attributes.remove(name); + break; + case REQUEST_SCOPE: + this.request.removeAttribute(name); + break; + case SESSION_SCOPE: + this.request.getSession().removeAttribute(name); + break; + case APPLICATION_SCOPE: + this.servletContext.removeAttribute(name); + break; + default: + throw new IllegalArgumentException("Invalid scope: " + scope); + } + } + + public int getAttributesScope(String name) { + if (getAttribute(name) != null) { + return PAGE_SCOPE; + } + else if (getAttribute(name, REQUEST_SCOPE) != null) { + return REQUEST_SCOPE; + } + else if (getAttribute(name, SESSION_SCOPE) != null) { + return SESSION_SCOPE; + } + else if (getAttribute(name, APPLICATION_SCOPE) != null) { + return APPLICATION_SCOPE; + } + else { + return 0; + } + } + + public Enumeration<String> getAttributeNames() { + return Collections.enumeration(this.attributes.keySet()); + } + + @SuppressWarnings("unchecked") + public Enumeration<String> getAttributeNamesInScope(int scope) { + switch (scope) { + case PAGE_SCOPE: + return getAttributeNames(); + case REQUEST_SCOPE: + return this.request.getAttributeNames(); + case SESSION_SCOPE: + HttpSession session = this.request.getSession(false); + return (session != null ? session.getAttributeNames() : null); + case APPLICATION_SCOPE: + return this.servletContext.getAttributeNames(); + default: + throw new IllegalArgumentException("Invalid scope: " + scope); + } + } + + public JspWriter getOut() { + if (this.out == null) { + this.out = new MockJspWriter(this.response); + } + return this.out; + } + + public ExpressionEvaluator getExpressionEvaluator() { + return new ExpressionEvaluator() { + public Expression parseExpression(String expression, Class expectedType, FunctionMapper fMapper) throws ELException { + throw new UnsupportedOperationException(); + } + public Object evaluate(String expression, Class expectedType, VariableResolver vResolver, FunctionMapper fMapper) throws ELException { + String key = expression.substring(2, expression.length() - 1); + return findAttribute(key); + } + }; + } + + public ELContext getELContext() { + return null; + } + + public VariableResolver getVariableResolver() { + return new VariableResolver() { + public Object resolveVariable(String pName) throws ELException { + if (pName.equals("pageContext")) { + return this; + } else { + return null; + } + } + }; + } + + public HttpSession getSession() { + return this.request.getSession(); + } + + public Object getPage() { + return this; + } + + public ServletRequest getRequest() { + return this.request; + } + + public ServletResponse getResponse() { + return this.response; + } + + public Exception getException() { + return null; + } + + public ServletConfig getServletConfig() { + return this.servletConfig; + } + + public ServletContext getServletContext() { + return this.servletContext; + } + + public void forward(String path) throws ServletException, IOException { + this.request.getRequestDispatcher(path).forward(this.request, this.response); + } + + public void include(String path) throws ServletException, IOException { + this.request.getRequestDispatcher(path).include(this.request, this.response); + } + + public void include(String path, boolean flush) throws ServletException, IOException { + this.request.getRequestDispatcher(path).include(this.request, this.response); + if (flush) { + this.response.flushBuffer(); + } + } + + public byte[] getContentAsByteArray() { + Assert.isTrue(this.response instanceof MockHttpServletResponse); + return ((MockHttpServletResponse) this.response).getContentAsByteArray(); + } + + public String getContentAsString() throws UnsupportedEncodingException { + Assert.isTrue(this.response instanceof MockHttpServletResponse); + return ((MockHttpServletResponse) this.response).getContentAsString(); + } + + public void handlePageException(Exception ex) throws ServletException, IOException { + throw new ServletException("Page exception", ex); + } + + public void handlePageException(Throwable ex) throws ServletException, IOException { + throw new ServletException("Page exception", ex); + } + +} diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockRequestDispatcher.java b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockRequestDispatcher.java index 396f0e7fd54..a87bea43c91 100644 --- a/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockRequestDispatcher.java +++ b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockRequestDispatcher.java @@ -1,91 +1,91 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.mock.web; - -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletResponseWrapper; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.util.Assert; - -/** - * Mock implementation of the {@link javax.servlet.RequestDispatcher} interface. - * - * <p>Used for testing the web framework; typically not necessary for - * testing application controllers. - * - * @author Rod Johnson - * @author Juergen Hoeller - * @since 1.0.2 - */ -public class MockRequestDispatcher implements RequestDispatcher { - - private final Log logger = LogFactory.getLog(getClass()); - - private final String url; - - - /** - * Create a new MockRequestDispatcher for the given URL. - * @param url the URL to dispatch to. - */ - public MockRequestDispatcher(String url) { - Assert.notNull(url, "URL must not be null"); - this.url = url; - } - - - public void forward(ServletRequest request, ServletResponse response) { - Assert.notNull(request, "Request must not be null"); - Assert.notNull(response, "Response must not be null"); - if (response.isCommitted()) { - throw new IllegalStateException("Cannot perform forward - response is already committed"); - } - getMockHttpServletResponse(response).setForwardedUrl(this.url); - if (logger.isDebugEnabled()) { - logger.debug("MockRequestDispatcher: forwarding to URL [" + this.url + "]"); - } - } - - public void include(ServletRequest request, ServletResponse response) { - Assert.notNull(request, "Request must not be null"); - Assert.notNull(response, "Response must not be null"); - getMockHttpServletResponse(response).addIncludedUrl(this.url); - if (logger.isDebugEnabled()) { - logger.debug("MockRequestDispatcher: including URL [" + this.url + "]"); - } - } - - /** - * Obtain the underlying MockHttpServletResponse, - * unwrapping {@link HttpServletResponseWrapper} decorators if necessary. - */ - protected MockHttpServletResponse getMockHttpServletResponse(ServletResponse response) { - if (response instanceof MockHttpServletResponse) { - return (MockHttpServletResponse) response; - } - if (response instanceof HttpServletResponseWrapper) { - return getMockHttpServletResponse(((HttpServletResponseWrapper) response).getResponse()); - } - throw new IllegalArgumentException("MockRequestDispatcher requires MockHttpServletResponse"); - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.mock.web; + +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletResponseWrapper; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.springframework.util.Assert; + +/** + * Mock implementation of the {@link javax.servlet.RequestDispatcher} interface. + * + * <p>Used for testing the web framework; typically not necessary for + * testing application controllers. + * + * @author Rod Johnson + * @author Juergen Hoeller + * @since 1.0.2 + */ +public class MockRequestDispatcher implements RequestDispatcher { + + private final Log logger = LogFactory.getLog(getClass()); + + private final String url; + + + /** + * Create a new MockRequestDispatcher for the given URL. + * @param url the URL to dispatch to. + */ + public MockRequestDispatcher(String url) { + Assert.notNull(url, "URL must not be null"); + this.url = url; + } + + + public void forward(ServletRequest request, ServletResponse response) { + Assert.notNull(request, "Request must not be null"); + Assert.notNull(response, "Response must not be null"); + if (response.isCommitted()) { + throw new IllegalStateException("Cannot perform forward - response is already committed"); + } + getMockHttpServletResponse(response).setForwardedUrl(this.url); + if (logger.isDebugEnabled()) { + logger.debug("MockRequestDispatcher: forwarding to URL [" + this.url + "]"); + } + } + + public void include(ServletRequest request, ServletResponse response) { + Assert.notNull(request, "Request must not be null"); + Assert.notNull(response, "Response must not be null"); + getMockHttpServletResponse(response).addIncludedUrl(this.url); + if (logger.isDebugEnabled()) { + logger.debug("MockRequestDispatcher: including URL [" + this.url + "]"); + } + } + + /** + * Obtain the underlying MockHttpServletResponse, + * unwrapping {@link HttpServletResponseWrapper} decorators if necessary. + */ + protected MockHttpServletResponse getMockHttpServletResponse(ServletResponse response) { + if (response instanceof MockHttpServletResponse) { + return (MockHttpServletResponse) response; + } + if (response instanceof HttpServletResponseWrapper) { + return getMockHttpServletResponse(((HttpServletResponseWrapper) response).getResponse()); + } + throw new IllegalArgumentException("MockRequestDispatcher requires MockHttpServletResponse"); + } + +} diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockServletConfig.java b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockServletConfig.java index 7d67a6cd419..c62ec1520d0 100644 --- a/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockServletConfig.java +++ b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockServletConfig.java @@ -1,103 +1,103 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.mock.web; - -import java.util.Collections; -import java.util.Enumeration; -import java.util.LinkedHashMap; -import java.util.Map; -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; - -import org.springframework.util.Assert; - -/** - * Mock implementation of the {@link javax.servlet.ServletConfig} interface. - * - * <p>Used for testing the web framework; typically not necessary for - * testing application controllers. - * - * @author Rod Johnson - * @author Juergen Hoeller - * @since 1.0.2 - */ -public class MockServletConfig implements ServletConfig { - - private final ServletContext servletContext; - - private final String servletName; - - private final Map<String, String> initParameters = new LinkedHashMap<String, String>(); - - - /** - * Create a new MockServletConfig with a default {@link MockServletContext}. - */ - public MockServletConfig() { - this(null, ""); - } - - /** - * Create a new MockServletConfig with a default {@link MockServletContext}. - * @param servletName the name of the servlet - */ - public MockServletConfig(String servletName) { - this(null, servletName); - } - - /** - * Create a new MockServletConfig. - * @param servletContext the ServletContext that the servlet runs in - */ - public MockServletConfig(ServletContext servletContext) { - this(servletContext, ""); - } - - /** - * Create a new MockServletConfig. - * @param servletContext the ServletContext that the servlet runs in - * @param servletName the name of the servlet - */ - public MockServletConfig(ServletContext servletContext, String servletName) { - this.servletContext = (servletContext != null ? servletContext : new MockServletContext()); - this.servletName = servletName; - } - - - public String getServletName() { - return this.servletName; - } - - public ServletContext getServletContext() { - return this.servletContext; - } - - public void addInitParameter(String name, String value) { - Assert.notNull(name, "Parameter name must not be null"); - this.initParameters.put(name, value); - } - - public String getInitParameter(String name) { - Assert.notNull(name, "Parameter name must not be null"); - return this.initParameters.get(name); - } - - public Enumeration<String> getInitParameterNames() { - return Collections.enumeration(this.initParameters.keySet()); - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.mock.web; + +import java.util.Collections; +import java.util.Enumeration; +import java.util.LinkedHashMap; +import java.util.Map; +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; + +import org.springframework.util.Assert; + +/** + * Mock implementation of the {@link javax.servlet.ServletConfig} interface. + * + * <p>Used for testing the web framework; typically not necessary for + * testing application controllers. + * + * @author Rod Johnson + * @author Juergen Hoeller + * @since 1.0.2 + */ +public class MockServletConfig implements ServletConfig { + + private final ServletContext servletContext; + + private final String servletName; + + private final Map<String, String> initParameters = new LinkedHashMap<String, String>(); + + + /** + * Create a new MockServletConfig with a default {@link MockServletContext}. + */ + public MockServletConfig() { + this(null, ""); + } + + /** + * Create a new MockServletConfig with a default {@link MockServletContext}. + * @param servletName the name of the servlet + */ + public MockServletConfig(String servletName) { + this(null, servletName); + } + + /** + * Create a new MockServletConfig. + * @param servletContext the ServletContext that the servlet runs in + */ + public MockServletConfig(ServletContext servletContext) { + this(servletContext, ""); + } + + /** + * Create a new MockServletConfig. + * @param servletContext the ServletContext that the servlet runs in + * @param servletName the name of the servlet + */ + public MockServletConfig(ServletContext servletContext, String servletName) { + this.servletContext = (servletContext != null ? servletContext : new MockServletContext()); + this.servletName = servletName; + } + + + public String getServletName() { + return this.servletName; + } + + public ServletContext getServletContext() { + return this.servletContext; + } + + public void addInitParameter(String name, String value) { + Assert.notNull(name, "Parameter name must not be null"); + this.initParameters.put(name, value); + } + + public String getInitParameter(String name) { + Assert.notNull(name, "Parameter name must not be null"); + return this.initParameters.get(name); + } + + public Enumeration<String> getInitParameterNames() { + return Collections.enumeration(this.initParameters.keySet()); + } + +} diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockServletContext.java b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockServletContext.java index 828b430e6c4..3e340f463ad 100644 --- a/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockServletContext.java +++ b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockServletContext.java @@ -1,492 +1,492 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.mock.web; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Collections; -import java.util.Enumeration; -import java.util.EventListener; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Set; -import javax.activation.FileTypeMap; -import javax.servlet.Filter; -import javax.servlet.FilterRegistration; -import javax.servlet.FilterRegistration.Dynamic; -import javax.servlet.RequestDispatcher; -import javax.servlet.Servlet; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRegistration; -import javax.servlet.SessionCookieConfig; -import javax.servlet.SessionTrackingMode; -import javax.servlet.descriptor.JspConfigDescriptor; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.core.io.DefaultResourceLoader; -import org.springframework.core.io.Resource; -import org.springframework.core.io.ResourceLoader; -import org.springframework.util.Assert; -import org.springframework.util.ObjectUtils; -import org.springframework.web.util.WebUtils; - -/** - * Mock implementation of the {@link javax.servlet.ServletContext} interface. - * - * <p>Used for testing the Spring web framework; only rarely necessary for testing - * application controllers. As long as application components don't explicitly - * access the ServletContext, ClassPathXmlApplicationContext or - * FileSystemXmlApplicationContext can be used to load the context files for testing, - * even for DispatcherServlet context definitions. - * - * <p>For setting up a full WebApplicationContext in a test environment, you can - * use XmlWebApplicationContext (or GenericWebApplicationContext), passing in an - * appropriate MockServletContext instance. You might want to configure your - * MockServletContext with a FileSystemResourceLoader in that case, to make your - * resource paths interpreted as relative file system locations. - * - * <p>A common setup is to point your JVM working directory to the root of your - * web application directory, in combination with filesystem-based resource loading. - * This allows to load the context files as used in the web application, with - * relative paths getting interpreted correctly. Such a setup will work with both - * FileSystemXmlApplicationContext (which will load straight from the file system) - * and XmlWebApplicationContext with an underlying MockServletContext (as long as - * the MockServletContext has been configured with a FileSystemResourceLoader). - * - * Supports the Servlet 3.0 API level, but throws {@link UnsupportedOperationException} - * for all methods introduced in Servlet 3.0. - * - * @author Rod Johnson - * @author Juergen Hoeller - * @author Chris Beams - * @since 1.0.2 - * @see #MockServletContext(org.springframework.core.io.ResourceLoader) - * @see org.springframework.web.context.support.XmlWebApplicationContext - * @see org.springframework.web.context.support.GenericWebApplicationContext - * @see org.springframework.context.support.ClassPathXmlApplicationContext - * @see org.springframework.context.support.FileSystemXmlApplicationContext - */ -public class MockServletContext implements ServletContext { - - private static final String TEMP_DIR_SYSTEM_PROPERTY = "java.io.tmpdir"; - - - private final Log logger = LogFactory.getLog(getClass()); - - private final ResourceLoader resourceLoader; - - private final String resourceBasePath; - - private String contextPath = ""; - - private int minorVersion = 5; - - private final Map<String, ServletContext> contexts = new HashMap<String, ServletContext>(); - - private final Map<String, String> initParameters = new LinkedHashMap<String, String>(); - - private final Map<String, Object> attributes = new LinkedHashMap<String, Object>(); - - private String servletContextName = "MockServletContext"; - - - /** - * Create a new MockServletContext, using no base path and a - * DefaultResourceLoader (i.e. the classpath root as WAR root). - * @see org.springframework.core.io.DefaultResourceLoader - */ - public MockServletContext() { - this("", null); - } - - /** - * Create a new MockServletContext, using a DefaultResourceLoader. - * @param resourceBasePath the WAR root directory (should not end with a slash) - * @see org.springframework.core.io.DefaultResourceLoader - */ - public MockServletContext(String resourceBasePath) { - this(resourceBasePath, null); - } - - /** - * Create a new MockServletContext, using the specified ResourceLoader - * and no base path. - * @param resourceLoader the ResourceLoader to use (or null for the default) - */ - public MockServletContext(ResourceLoader resourceLoader) { - this("", resourceLoader); - } - - /** - * Create a new MockServletContext. - * @param resourceBasePath the WAR root directory (should not end with a slash) - * @param resourceLoader the ResourceLoader to use (or null for the default) - */ - public MockServletContext(String resourceBasePath, ResourceLoader resourceLoader) { - this.resourceLoader = (resourceLoader != null ? resourceLoader : new DefaultResourceLoader()); - this.resourceBasePath = (resourceBasePath != null ? resourceBasePath : ""); - - // Use JVM temp dir as ServletContext temp dir. - String tempDir = System.getProperty(TEMP_DIR_SYSTEM_PROPERTY); - if (tempDir != null) { - this.attributes.put(WebUtils.TEMP_DIR_CONTEXT_ATTRIBUTE, new File(tempDir)); - } - } - - - /** - * Build a full resource location for the given path, - * prepending the resource base path of this MockServletContext. - * @param path the path as specified - * @return the full resource path - */ - protected String getResourceLocation(String path) { - if (!path.startsWith("/")) { - path = "/" + path; - } - return this.resourceBasePath + path; - } - - - public void setContextPath(String contextPath) { - this.contextPath = (contextPath != null ? contextPath : ""); - } - - /* This is a Servlet API 2.5 method. */ - public String getContextPath() { - return this.contextPath; - } - - public void registerContext(String contextPath, ServletContext context) { - this.contexts.put(contextPath, context); - } - - public ServletContext getContext(String contextPath) { - if (this.contextPath.equals(contextPath)) { - return this; - } - return this.contexts.get(contextPath); - } - - public int getMajorVersion() { - return 2; - } - - public void setMinorVersion(int minorVersion) { - if (minorVersion < 3 || minorVersion > 5) { - throw new IllegalArgumentException("Only Servlet minor versions between 3 and 5 are supported"); - } - this.minorVersion = minorVersion; - } - - public int getMinorVersion() { - return this.minorVersion; - } - - public String getMimeType(String filePath) { - return MimeTypeResolver.getMimeType(filePath); - } - - public Set<String> getResourcePaths(String path) { - String actualPath = (path.endsWith("/") ? path : path + "/"); - Resource resource = this.resourceLoader.getResource(getResourceLocation(actualPath)); - try { - File file = resource.getFile(); - String[] fileList = file.list(); - if (ObjectUtils.isEmpty(fileList)) { - return null; - } - Set<String> resourcePaths = new LinkedHashSet<String>(fileList.length); - for (String fileEntry : fileList) { - String resultPath = actualPath + fileEntry; - if (resource.createRelative(fileEntry).getFile().isDirectory()) { - resultPath += "/"; - } - resourcePaths.add(resultPath); - } - return resourcePaths; - } - catch (IOException ex) { - logger.warn("Couldn't get resource paths for " + resource, ex); - return null; - } - } - - public URL getResource(String path) throws MalformedURLException { - Resource resource = this.resourceLoader.getResource(getResourceLocation(path)); - if (!resource.exists()) { - return null; - } - try { - return resource.getURL(); - } - catch (MalformedURLException ex) { - throw ex; - } - catch (IOException ex) { - logger.warn("Couldn't get URL for " + resource, ex); - return null; - } - } - - public InputStream getResourceAsStream(String path) { - Resource resource = this.resourceLoader.getResource(getResourceLocation(path)); - if (!resource.exists()) { - return null; - } - try { - return resource.getInputStream(); - } - catch (IOException ex) { - logger.warn("Couldn't open InputStream for " + resource, ex); - return null; - } - } - - public RequestDispatcher getRequestDispatcher(String path) { - if (!path.startsWith("/")) { - throw new IllegalArgumentException("RequestDispatcher path at ServletContext level must start with '/'"); - } - return new MockRequestDispatcher(path); - } - - public RequestDispatcher getNamedDispatcher(String path) { - return null; - } - - public Servlet getServlet(String name) { - return null; - } - - public Enumeration<Servlet> getServlets() { - return Collections.enumeration(new HashSet<Servlet>()); - } - - public Enumeration<String> getServletNames() { - return Collections.enumeration(new HashSet<String>()); - } - - public void log(String message) { - logger.info(message); - } - - public void log(Exception ex, String message) { - logger.info(message, ex); - } - - public void log(String message, Throwable ex) { - logger.info(message, ex); - } - - public String getRealPath(String path) { - Resource resource = this.resourceLoader.getResource(getResourceLocation(path)); - try { - return resource.getFile().getAbsolutePath(); - } - catch (IOException ex) { - logger.warn("Couldn't determine real path of resource " + resource, ex); - return null; - } - } - - public String getServerInfo() { - return "MockServletContext"; - } - - public String getInitParameter(String name) { - Assert.notNull(name, "Parameter name must not be null"); - return this.initParameters.get(name); - } - - public void addInitParameter(String name, String value) { - Assert.notNull(name, "Parameter name must not be null"); - this.initParameters.put(name, value); - } - - public Enumeration<String> getInitParameterNames() { - return Collections.enumeration(this.initParameters.keySet()); - } - - public Object getAttribute(String name) { - Assert.notNull(name, "Attribute name must not be null"); - return this.attributes.get(name); - } - - public Enumeration<String> getAttributeNames() { - return Collections.enumeration(this.attributes.keySet()); - } - - public void setAttribute(String name, Object value) { - Assert.notNull(name, "Attribute name must not be null"); - if (value != null) { - this.attributes.put(name, value); - } - else { - this.attributes.remove(name); - } - } - - public void removeAttribute(String name) { - Assert.notNull(name, "Attribute name must not be null"); - this.attributes.remove(name); - } - - public void setServletContextName(String servletContextName) { - this.servletContextName = servletContextName; - } - - public String getServletContextName() { - return this.servletContextName; - } - - - /** - * Inner factory class used to just introduce a Java Activation Framework - * dependency when actually asked to resolve a MIME type. - */ - private static class MimeTypeResolver { - - public static String getMimeType(String filePath) { - return FileTypeMap.getDefaultFileTypeMap().getContentType(filePath); - } - } - - - //--------------------------------------------------------------------- - // Methods introduced in Servlet 3.0 - //--------------------------------------------------------------------- - - public Dynamic addFilter(String arg0, String arg1) { - throw new UnsupportedOperationException(); - } - - public Dynamic addFilter(String arg0, Filter arg1) { - throw new UnsupportedOperationException(); - } - - public Dynamic addFilter(String arg0, Class<? extends Filter> arg1) { - throw new UnsupportedOperationException(); - } - - public void addListener(Class<? extends EventListener> arg0) { - throw new UnsupportedOperationException(); - } - - public void addListener(String arg0) { - throw new UnsupportedOperationException(); - } - - public <T extends EventListener> void addListener(T arg0) { - throw new UnsupportedOperationException(); - } - - public javax.servlet.ServletRegistration.Dynamic addServlet(String arg0, String arg1) { - throw new UnsupportedOperationException(); - } - - public javax.servlet.ServletRegistration.Dynamic addServlet(String arg0, - Servlet arg1) { - throw new UnsupportedOperationException(); - } - - public javax.servlet.ServletRegistration.Dynamic addServlet(String arg0, - Class<? extends Servlet> arg1) { - throw new UnsupportedOperationException(); - } - - public <T extends Filter> T createFilter(Class<T> arg0) - throws ServletException { - throw new UnsupportedOperationException(); - } - - public <T extends EventListener> T createListener(Class<T> arg0) - throws ServletException { - throw new UnsupportedOperationException(); - } - - public <T extends Servlet> T createServlet(Class<T> arg0) - throws ServletException { - throw new UnsupportedOperationException(); - } - - public void declareRoles(String... arg0) { - throw new UnsupportedOperationException(); - } - - public ClassLoader getClassLoader() { - throw new UnsupportedOperationException(); - } - - public Set<SessionTrackingMode> getDefaultSessionTrackingModes() { - throw new UnsupportedOperationException(); - } - - public int getEffectiveMajorVersion() { - throw new UnsupportedOperationException(); - } - - public int getEffectiveMinorVersion() { - throw new UnsupportedOperationException(); - } - - public Set<SessionTrackingMode> getEffectiveSessionTrackingModes() { - throw new UnsupportedOperationException(); - } - - public FilterRegistration getFilterRegistration(String arg0) { - throw new UnsupportedOperationException(); - } - - public Map<String, ? extends FilterRegistration> getFilterRegistrations() { - throw new UnsupportedOperationException(); - } - - public JspConfigDescriptor getJspConfigDescriptor() { - throw new UnsupportedOperationException(); - } - - public ServletRegistration getServletRegistration(String arg0) { - throw new UnsupportedOperationException(); - } - - public Map<String, ? extends ServletRegistration> getServletRegistrations() { - throw new UnsupportedOperationException(); - } - - public SessionCookieConfig getSessionCookieConfig() { - throw new UnsupportedOperationException(); - } - - public boolean setInitParameter(String arg0, String arg1) { - throw new UnsupportedOperationException(); - } - - public void setSessionTrackingModes(Set<SessionTrackingMode> arg0) - throws IllegalStateException, IllegalArgumentException { - throw new UnsupportedOperationException(); - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.mock.web; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Collections; +import java.util.Enumeration; +import java.util.EventListener; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; +import javax.activation.FileTypeMap; +import javax.servlet.Filter; +import javax.servlet.FilterRegistration; +import javax.servlet.FilterRegistration.Dynamic; +import javax.servlet.RequestDispatcher; +import javax.servlet.Servlet; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletRegistration; +import javax.servlet.SessionCookieConfig; +import javax.servlet.SessionTrackingMode; +import javax.servlet.descriptor.JspConfigDescriptor; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.springframework.core.io.DefaultResourceLoader; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.springframework.util.Assert; +import org.springframework.util.ObjectUtils; +import org.springframework.web.util.WebUtils; + +/** + * Mock implementation of the {@link javax.servlet.ServletContext} interface. + * + * <p>Used for testing the Spring web framework; only rarely necessary for testing + * application controllers. As long as application components don't explicitly + * access the ServletContext, ClassPathXmlApplicationContext or + * FileSystemXmlApplicationContext can be used to load the context files for testing, + * even for DispatcherServlet context definitions. + * + * <p>For setting up a full WebApplicationContext in a test environment, you can + * use XmlWebApplicationContext (or GenericWebApplicationContext), passing in an + * appropriate MockServletContext instance. You might want to configure your + * MockServletContext with a FileSystemResourceLoader in that case, to make your + * resource paths interpreted as relative file system locations. + * + * <p>A common setup is to point your JVM working directory to the root of your + * web application directory, in combination with filesystem-based resource loading. + * This allows to load the context files as used in the web application, with + * relative paths getting interpreted correctly. Such a setup will work with both + * FileSystemXmlApplicationContext (which will load straight from the file system) + * and XmlWebApplicationContext with an underlying MockServletContext (as long as + * the MockServletContext has been configured with a FileSystemResourceLoader). + * + * Supports the Servlet 3.0 API level, but throws {@link UnsupportedOperationException} + * for all methods introduced in Servlet 3.0. + * + * @author Rod Johnson + * @author Juergen Hoeller + * @author Chris Beams + * @since 1.0.2 + * @see #MockServletContext(org.springframework.core.io.ResourceLoader) + * @see org.springframework.web.context.support.XmlWebApplicationContext + * @see org.springframework.web.context.support.GenericWebApplicationContext + * @see org.springframework.context.support.ClassPathXmlApplicationContext + * @see org.springframework.context.support.FileSystemXmlApplicationContext + */ +public class MockServletContext implements ServletContext { + + private static final String TEMP_DIR_SYSTEM_PROPERTY = "java.io.tmpdir"; + + + private final Log logger = LogFactory.getLog(getClass()); + + private final ResourceLoader resourceLoader; + + private final String resourceBasePath; + + private String contextPath = ""; + + private int minorVersion = 5; + + private final Map<String, ServletContext> contexts = new HashMap<String, ServletContext>(); + + private final Map<String, String> initParameters = new LinkedHashMap<String, String>(); + + private final Map<String, Object> attributes = new LinkedHashMap<String, Object>(); + + private String servletContextName = "MockServletContext"; + + + /** + * Create a new MockServletContext, using no base path and a + * DefaultResourceLoader (i.e. the classpath root as WAR root). + * @see org.springframework.core.io.DefaultResourceLoader + */ + public MockServletContext() { + this("", null); + } + + /** + * Create a new MockServletContext, using a DefaultResourceLoader. + * @param resourceBasePath the WAR root directory (should not end with a slash) + * @see org.springframework.core.io.DefaultResourceLoader + */ + public MockServletContext(String resourceBasePath) { + this(resourceBasePath, null); + } + + /** + * Create a new MockServletContext, using the specified ResourceLoader + * and no base path. + * @param resourceLoader the ResourceLoader to use (or null for the default) + */ + public MockServletContext(ResourceLoader resourceLoader) { + this("", resourceLoader); + } + + /** + * Create a new MockServletContext. + * @param resourceBasePath the WAR root directory (should not end with a slash) + * @param resourceLoader the ResourceLoader to use (or null for the default) + */ + public MockServletContext(String resourceBasePath, ResourceLoader resourceLoader) { + this.resourceLoader = (resourceLoader != null ? resourceLoader : new DefaultResourceLoader()); + this.resourceBasePath = (resourceBasePath != null ? resourceBasePath : ""); + + // Use JVM temp dir as ServletContext temp dir. + String tempDir = System.getProperty(TEMP_DIR_SYSTEM_PROPERTY); + if (tempDir != null) { + this.attributes.put(WebUtils.TEMP_DIR_CONTEXT_ATTRIBUTE, new File(tempDir)); + } + } + + + /** + * Build a full resource location for the given path, + * prepending the resource base path of this MockServletContext. + * @param path the path as specified + * @return the full resource path + */ + protected String getResourceLocation(String path) { + if (!path.startsWith("/")) { + path = "/" + path; + } + return this.resourceBasePath + path; + } + + + public void setContextPath(String contextPath) { + this.contextPath = (contextPath != null ? contextPath : ""); + } + + /* This is a Servlet API 2.5 method. */ + public String getContextPath() { + return this.contextPath; + } + + public void registerContext(String contextPath, ServletContext context) { + this.contexts.put(contextPath, context); + } + + public ServletContext getContext(String contextPath) { + if (this.contextPath.equals(contextPath)) { + return this; + } + return this.contexts.get(contextPath); + } + + public int getMajorVersion() { + return 2; + } + + public void setMinorVersion(int minorVersion) { + if (minorVersion < 3 || minorVersion > 5) { + throw new IllegalArgumentException("Only Servlet minor versions between 3 and 5 are supported"); + } + this.minorVersion = minorVersion; + } + + public int getMinorVersion() { + return this.minorVersion; + } + + public String getMimeType(String filePath) { + return MimeTypeResolver.getMimeType(filePath); + } + + public Set<String> getResourcePaths(String path) { + String actualPath = (path.endsWith("/") ? path : path + "/"); + Resource resource = this.resourceLoader.getResource(getResourceLocation(actualPath)); + try { + File file = resource.getFile(); + String[] fileList = file.list(); + if (ObjectUtils.isEmpty(fileList)) { + return null; + } + Set<String> resourcePaths = new LinkedHashSet<String>(fileList.length); + for (String fileEntry : fileList) { + String resultPath = actualPath + fileEntry; + if (resource.createRelative(fileEntry).getFile().isDirectory()) { + resultPath += "/"; + } + resourcePaths.add(resultPath); + } + return resourcePaths; + } + catch (IOException ex) { + logger.warn("Couldn't get resource paths for " + resource, ex); + return null; + } + } + + public URL getResource(String path) throws MalformedURLException { + Resource resource = this.resourceLoader.getResource(getResourceLocation(path)); + if (!resource.exists()) { + return null; + } + try { + return resource.getURL(); + } + catch (MalformedURLException ex) { + throw ex; + } + catch (IOException ex) { + logger.warn("Couldn't get URL for " + resource, ex); + return null; + } + } + + public InputStream getResourceAsStream(String path) { + Resource resource = this.resourceLoader.getResource(getResourceLocation(path)); + if (!resource.exists()) { + return null; + } + try { + return resource.getInputStream(); + } + catch (IOException ex) { + logger.warn("Couldn't open InputStream for " + resource, ex); + return null; + } + } + + public RequestDispatcher getRequestDispatcher(String path) { + if (!path.startsWith("/")) { + throw new IllegalArgumentException("RequestDispatcher path at ServletContext level must start with '/'"); + } + return new MockRequestDispatcher(path); + } + + public RequestDispatcher getNamedDispatcher(String path) { + return null; + } + + public Servlet getServlet(String name) { + return null; + } + + public Enumeration<Servlet> getServlets() { + return Collections.enumeration(new HashSet<Servlet>()); + } + + public Enumeration<String> getServletNames() { + return Collections.enumeration(new HashSet<String>()); + } + + public void log(String message) { + logger.info(message); + } + + public void log(Exception ex, String message) { + logger.info(message, ex); + } + + public void log(String message, Throwable ex) { + logger.info(message, ex); + } + + public String getRealPath(String path) { + Resource resource = this.resourceLoader.getResource(getResourceLocation(path)); + try { + return resource.getFile().getAbsolutePath(); + } + catch (IOException ex) { + logger.warn("Couldn't determine real path of resource " + resource, ex); + return null; + } + } + + public String getServerInfo() { + return "MockServletContext"; + } + + public String getInitParameter(String name) { + Assert.notNull(name, "Parameter name must not be null"); + return this.initParameters.get(name); + } + + public void addInitParameter(String name, String value) { + Assert.notNull(name, "Parameter name must not be null"); + this.initParameters.put(name, value); + } + + public Enumeration<String> getInitParameterNames() { + return Collections.enumeration(this.initParameters.keySet()); + } + + public Object getAttribute(String name) { + Assert.notNull(name, "Attribute name must not be null"); + return this.attributes.get(name); + } + + public Enumeration<String> getAttributeNames() { + return Collections.enumeration(this.attributes.keySet()); + } + + public void setAttribute(String name, Object value) { + Assert.notNull(name, "Attribute name must not be null"); + if (value != null) { + this.attributes.put(name, value); + } + else { + this.attributes.remove(name); + } + } + + public void removeAttribute(String name) { + Assert.notNull(name, "Attribute name must not be null"); + this.attributes.remove(name); + } + + public void setServletContextName(String servletContextName) { + this.servletContextName = servletContextName; + } + + public String getServletContextName() { + return this.servletContextName; + } + + + /** + * Inner factory class used to just introduce a Java Activation Framework + * dependency when actually asked to resolve a MIME type. + */ + private static class MimeTypeResolver { + + public static String getMimeType(String filePath) { + return FileTypeMap.getDefaultFileTypeMap().getContentType(filePath); + } + } + + + //--------------------------------------------------------------------- + // Methods introduced in Servlet 3.0 + //--------------------------------------------------------------------- + + public Dynamic addFilter(String arg0, String arg1) { + throw new UnsupportedOperationException(); + } + + public Dynamic addFilter(String arg0, Filter arg1) { + throw new UnsupportedOperationException(); + } + + public Dynamic addFilter(String arg0, Class<? extends Filter> arg1) { + throw new UnsupportedOperationException(); + } + + public void addListener(Class<? extends EventListener> arg0) { + throw new UnsupportedOperationException(); + } + + public void addListener(String arg0) { + throw new UnsupportedOperationException(); + } + + public <T extends EventListener> void addListener(T arg0) { + throw new UnsupportedOperationException(); + } + + public javax.servlet.ServletRegistration.Dynamic addServlet(String arg0, String arg1) { + throw new UnsupportedOperationException(); + } + + public javax.servlet.ServletRegistration.Dynamic addServlet(String arg0, + Servlet arg1) { + throw new UnsupportedOperationException(); + } + + public javax.servlet.ServletRegistration.Dynamic addServlet(String arg0, + Class<? extends Servlet> arg1) { + throw new UnsupportedOperationException(); + } + + public <T extends Filter> T createFilter(Class<T> arg0) + throws ServletException { + throw new UnsupportedOperationException(); + } + + public <T extends EventListener> T createListener(Class<T> arg0) + throws ServletException { + throw new UnsupportedOperationException(); + } + + public <T extends Servlet> T createServlet(Class<T> arg0) + throws ServletException { + throw new UnsupportedOperationException(); + } + + public void declareRoles(String... arg0) { + throw new UnsupportedOperationException(); + } + + public ClassLoader getClassLoader() { + throw new UnsupportedOperationException(); + } + + public Set<SessionTrackingMode> getDefaultSessionTrackingModes() { + throw new UnsupportedOperationException(); + } + + public int getEffectiveMajorVersion() { + throw new UnsupportedOperationException(); + } + + public int getEffectiveMinorVersion() { + throw new UnsupportedOperationException(); + } + + public Set<SessionTrackingMode> getEffectiveSessionTrackingModes() { + throw new UnsupportedOperationException(); + } + + public FilterRegistration getFilterRegistration(String arg0) { + throw new UnsupportedOperationException(); + } + + public Map<String, ? extends FilterRegistration> getFilterRegistrations() { + throw new UnsupportedOperationException(); + } + + public JspConfigDescriptor getJspConfigDescriptor() { + throw new UnsupportedOperationException(); + } + + public ServletRegistration getServletRegistration(String arg0) { + throw new UnsupportedOperationException(); + } + + public Map<String, ? extends ServletRegistration> getServletRegistrations() { + throw new UnsupportedOperationException(); + } + + public SessionCookieConfig getSessionCookieConfig() { + throw new UnsupportedOperationException(); + } + + public boolean setInitParameter(String arg0, String arg1) { + throw new UnsupportedOperationException(); + } + + public void setSessionTrackingModes(Set<SessionTrackingMode> arg0) + throws IllegalStateException, IllegalArgumentException { + throw new UnsupportedOperationException(); + } + +} diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/util/SerializationTestUtils.java b/org.springframework.web.servlet/src/test/java/org/springframework/util/SerializationTestUtils.java index d920a3b4ffb..9ae4f54ec24 100644 --- a/org.springframework.web.servlet/src/test/java/org/springframework/util/SerializationTestUtils.java +++ b/org.springframework.web.servlet/src/test/java/org/springframework/util/SerializationTestUtils.java @@ -1,65 +1,65 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.util; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.NotSerializableException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.OutputStream; - -/** - * Utilities for testing serializability of objects. - * Exposes static methods for use in other test cases. - * - * @author Rod Johnson - */ -public class SerializationTestUtils { - - public static void testSerialization(Object o) throws IOException { - OutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream oos = new ObjectOutputStream(baos); - oos.writeObject(o); - } - - public static boolean isSerializable(Object o) throws IOException { - try { - testSerialization(o); - return true; - } - catch (NotSerializableException ex) { - return false; - } - } - - public static Object serializeAndDeserialize(Object o) throws IOException, ClassNotFoundException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream oos = new ObjectOutputStream(baos); - oos.writeObject(o); - oos.flush(); - baos.flush(); - byte[] bytes = baos.toByteArray(); - - ByteArrayInputStream is = new ByteArrayInputStream(bytes); - ObjectInputStream ois = new ObjectInputStream(is); - Object o2 = ois.readObject(); - return o2; - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.util; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.NotSerializableException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; + +/** + * Utilities for testing serializability of objects. + * Exposes static methods for use in other test cases. + * + * @author Rod Johnson + */ +public class SerializationTestUtils { + + public static void testSerialization(Object o) throws IOException { + OutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(o); + } + + public static boolean isSerializable(Object o) throws IOException { + try { + testSerialization(o); + return true; + } + catch (NotSerializableException ex) { + return false; + } + } + + public static Object serializeAndDeserialize(Object o) throws IOException, ClassNotFoundException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(o); + oos.flush(); + baos.flush(); + byte[] bytes = baos.toByteArray(); + + ByteArrayInputStream is = new ByteArrayInputStream(bytes); + ObjectInputStream ois = new ObjectInputStream(is); + Object o2 = ois.readObject(); + return o2; + } + +} diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/view/tiles2/TilesConfigurerTests.java b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/view/tiles2/TilesConfigurerTests.java index 341b98eb592..3c9045b32f3 100644 --- a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/view/tiles2/TilesConfigurerTests.java +++ b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/view/tiles2/TilesConfigurerTests.java @@ -1,52 +1,52 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.servlet.view.tiles2; - -import org.apache.tiles.context.TilesRequestContext; -import org.apache.tiles.impl.BasicTilesContainer; -import org.apache.tiles.servlet.context.ServletTilesRequestContext; -import org.apache.tiles.servlet.context.ServletUtil; -import static org.junit.Assert.*; -import org.junit.Test; - -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; -import org.springframework.mock.web.MockServletContext; - -/** - * @author Juergen Hoeller - * */ -public class TilesConfigurerTests { - - @Test - public void simpleBootstrap() { - MockServletContext sc = new MockServletContext(); - TilesConfigurer tc = new TilesConfigurer(); - tc.setDefinitions(new String[] {"/org/springframework/web/servlet/view/tiles2/tiles-definitions.xml"}); - tc.setCheckRefresh(true); - tc.setServletContext(sc); - tc.afterPropertiesSet(); - - BasicTilesContainer container = (BasicTilesContainer) ServletUtil.getContainer(sc); - TilesRequestContext requestContext = new ServletTilesRequestContext( - container.getApplicationContext(), new MockHttpServletRequest(), new MockHttpServletResponse()); - assertNotNull(container.getDefinitionsFactory().getDefinition("test", requestContext)); - - tc.destroy(); - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.web.servlet.view.tiles2; + +import org.apache.tiles.context.TilesRequestContext; +import org.apache.tiles.impl.BasicTilesContainer; +import org.apache.tiles.servlet.context.ServletTilesRequestContext; +import org.apache.tiles.servlet.context.ServletUtil; +import static org.junit.Assert.*; +import org.junit.Test; + +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.mock.web.MockServletContext; + +/** + * @author Juergen Hoeller + * */ +public class TilesConfigurerTests { + + @Test + public void simpleBootstrap() { + MockServletContext sc = new MockServletContext(); + TilesConfigurer tc = new TilesConfigurer(); + tc.setDefinitions(new String[] {"/org/springframework/web/servlet/view/tiles2/tiles-definitions.xml"}); + tc.setCheckRefresh(true); + tc.setServletContext(sc); + tc.afterPropertiesSet(); + + BasicTilesContainer container = (BasicTilesContainer) ServletUtil.getContainer(sc); + TilesRequestContext requestContext = new ServletTilesRequestContext( + container.getApplicationContext(), new MockHttpServletRequest(), new MockHttpServletResponse()); + assertNotNull(container.getDefinitionsFactory().getDefinition("test", requestContext)); + + tc.destroy(); + } + +} diff --git a/org.springframework.web/src/main/java/org/springframework/http/MediaTypeEditor.java b/org.springframework.web/src/main/java/org/springframework/http/MediaTypeEditor.java index 1ae84df853c..be3f73c37a6 100644 --- a/org.springframework.web/src/main/java/org/springframework/http/MediaTypeEditor.java +++ b/org.springframework.web/src/main/java/org/springframework/http/MediaTypeEditor.java @@ -1,50 +1,50 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.http; - -import java.beans.PropertyEditorSupport; - -import org.springframework.util.StringUtils; - -/** - * {@link java.beans.PropertyEditor Editor} for {@link MediaType} - * descriptors, to automatically convert <code>String</code> specifications - * (e.g. <code>"text/html"</code>) to <code>MediaType</code> properties. - * - * @author Juergen Hoeller - * @since 3.0 - * @see MediaType - */ -public class MediaTypeEditor extends PropertyEditorSupport { - - @Override - public void setAsText(String text) { - if (StringUtils.hasText(text)) { - setValue(MediaType.parseMediaType(text)); - } - else { - setValue(null); - } - } - - @Override - public String getAsText() { - MediaType mediaType = (MediaType) getValue(); - return (mediaType != null ? mediaType.toString() : ""); - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.http; + +import java.beans.PropertyEditorSupport; + +import org.springframework.util.StringUtils; + +/** + * {@link java.beans.PropertyEditor Editor} for {@link MediaType} + * descriptors, to automatically convert <code>String</code> specifications + * (e.g. <code>"text/html"</code>) to <code>MediaType</code> properties. + * + * @author Juergen Hoeller + * @since 3.0 + * @see MediaType + */ +public class MediaTypeEditor extends PropertyEditorSupport { + + @Override + public void setAsText(String text) { + if (StringUtils.hasText(text)) { + setValue(MediaType.parseMediaType(text)); + } + else { + setValue(null); + } + } + + @Override + public String getAsText() { + MediaType mediaType = (MediaType) getValue(); + return (mediaType != null ? mediaType.toString() : ""); + } + +} diff --git a/org.springframework.web/src/main/java/org/springframework/http/converter/xml/XmlAwareFormHttpMessageConverter.java b/org.springframework.web/src/main/java/org/springframework/http/converter/xml/XmlAwareFormHttpMessageConverter.java index 0db64e2b879..788fc132416 100644 --- a/org.springframework.web/src/main/java/org/springframework/http/converter/xml/XmlAwareFormHttpMessageConverter.java +++ b/org.springframework.web/src/main/java/org/springframework/http/converter/xml/XmlAwareFormHttpMessageConverter.java @@ -1,35 +1,35 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.http.converter.xml; - -import org.springframework.http.converter.FormHttpMessageConverter; - -/** - * Extension of {@link org.springframework.http.converter.FormHttpMessageConverter}, - * adding support for XML-based parts through a {@link SourceHttpMessageConverter}. - * - * @author Juergen Hoeller - * @since 3.0.3 - */ -public class XmlAwareFormHttpMessageConverter extends FormHttpMessageConverter { - - public XmlAwareFormHttpMessageConverter() { - super(); - addPartConverter(new SourceHttpMessageConverter()); - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.http.converter.xml; + +import org.springframework.http.converter.FormHttpMessageConverter; + +/** + * Extension of {@link org.springframework.http.converter.FormHttpMessageConverter}, + * adding support for XML-based parts through a {@link SourceHttpMessageConverter}. + * + * @author Juergen Hoeller + * @since 3.0.3 + */ +public class XmlAwareFormHttpMessageConverter extends FormHttpMessageConverter { + + public XmlAwareFormHttpMessageConverter() { + super(); + addPartConverter(new SourceHttpMessageConverter()); + } + +} diff --git a/org.springframework.web/src/main/java/org/springframework/web/bind/UnsatisfiedServletRequestParameterException.java b/org.springframework.web/src/main/java/org/springframework/web/bind/UnsatisfiedServletRequestParameterException.java index 8cd7d019bca..c067b432eed 100644 --- a/org.springframework.web/src/main/java/org/springframework/web/bind/UnsatisfiedServletRequestParameterException.java +++ b/org.springframework.web/src/main/java/org/springframework/web/bind/UnsatisfiedServletRequestParameterException.java @@ -1,88 +1,88 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.bind; - -import java.util.Iterator; -import java.util.Map; - -import org.springframework.util.ObjectUtils; -import org.springframework.util.StringUtils; - -/** - * {@link ServletRequestBindingException} subclass that indicates an unsatisfied - * parameter condition, as typically expressed using an <code>@RequestMapping</code> - * annotation at the <code>@Controller</code> type level. - * - * @author Juergen Hoeller - * @since 3.0 - * @see org.springframework.web.bind.annotation.RequestMapping#params() - */ -public class UnsatisfiedServletRequestParameterException extends ServletRequestBindingException { - - private final String[] paramConditions; - - private final Map<String, String[]> actualParams; - - - /** - * Create a new UnsatisfiedServletRequestParameterException. - * @param paramConditions the parameter conditions that have been violated - * @param actualParams the actual parameter Map associated with the ServletRequest - */ - @SuppressWarnings("unchecked") - public UnsatisfiedServletRequestParameterException(String[] paramConditions, Map actualParams) { - super(""); - this.paramConditions = paramConditions; - this.actualParams = (Map<String, String[]>) actualParams; - } - - - @Override - public String getMessage() { - return "Parameter conditions \"" + StringUtils.arrayToDelimitedString(this.paramConditions, ", ") + - "\" not met for actual request parameters: " + requestParameterMapToString(this.actualParams); - } - - private static String requestParameterMapToString(Map<String, String[]> actualParams) { - StringBuilder result = new StringBuilder(); - for (Iterator<Map.Entry<String, String[]>> it = actualParams.entrySet().iterator(); it.hasNext();) { - Map.Entry<String, String[]> entry = it.next(); - result.append(entry.getKey()).append('=').append(ObjectUtils.nullSafeToString(entry.getValue())); - if (it.hasNext()) { - result.append(", "); - } - } - return result.toString(); - } - - /** - * Return the parameter conditions that have been violated. - * @see org.springframework.web.bind.annotation.RequestMapping#params() - */ - public final String[] getParamConditions() { - return this.paramConditions; - } - - /** - * Return the actual parameter Map associated with the ServletRequest. - * @see javax.servlet.ServletRequest#getParameterMap() - */ - public final Map<String, String[]> getActualParams() { - return this.actualParams; - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.web.bind; + +import java.util.Iterator; +import java.util.Map; + +import org.springframework.util.ObjectUtils; +import org.springframework.util.StringUtils; + +/** + * {@link ServletRequestBindingException} subclass that indicates an unsatisfied + * parameter condition, as typically expressed using an <code>@RequestMapping</code> + * annotation at the <code>@Controller</code> type level. + * + * @author Juergen Hoeller + * @since 3.0 + * @see org.springframework.web.bind.annotation.RequestMapping#params() + */ +public class UnsatisfiedServletRequestParameterException extends ServletRequestBindingException { + + private final String[] paramConditions; + + private final Map<String, String[]> actualParams; + + + /** + * Create a new UnsatisfiedServletRequestParameterException. + * @param paramConditions the parameter conditions that have been violated + * @param actualParams the actual parameter Map associated with the ServletRequest + */ + @SuppressWarnings("unchecked") + public UnsatisfiedServletRequestParameterException(String[] paramConditions, Map actualParams) { + super(""); + this.paramConditions = paramConditions; + this.actualParams = (Map<String, String[]>) actualParams; + } + + + @Override + public String getMessage() { + return "Parameter conditions \"" + StringUtils.arrayToDelimitedString(this.paramConditions, ", ") + + "\" not met for actual request parameters: " + requestParameterMapToString(this.actualParams); + } + + private static String requestParameterMapToString(Map<String, String[]> actualParams) { + StringBuilder result = new StringBuilder(); + for (Iterator<Map.Entry<String, String[]>> it = actualParams.entrySet().iterator(); it.hasNext();) { + Map.Entry<String, String[]> entry = it.next(); + result.append(entry.getKey()).append('=').append(ObjectUtils.nullSafeToString(entry.getValue())); + if (it.hasNext()) { + result.append(", "); + } + } + return result.toString(); + } + + /** + * Return the parameter conditions that have been violated. + * @see org.springframework.web.bind.annotation.RequestMapping#params() + */ + public final String[] getParamConditions() { + return this.paramConditions; + } + + /** + * Return the actual parameter Map associated with the ServletRequest. + * @see javax.servlet.ServletRequest#getParameterMap() + */ + public final Map<String, String[]> getActualParams() { + return this.actualParams; + } + +} diff --git a/org.springframework.web/src/main/java/org/springframework/web/bind/annotation/Mapping.java b/org.springframework.web/src/main/java/org/springframework/web/bind/annotation/Mapping.java index afbd1f2e723..020d497321b 100644 --- a/org.springframework.web/src/main/java/org/springframework/web/bind/annotation/Mapping.java +++ b/org.springframework.web/src/main/java/org/springframework/web/bind/annotation/Mapping.java @@ -1,35 +1,35 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.bind.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Meta annotation that indicates a web mapping annotation. - * - * @author Juergen Hoeller - * @since 3.0 - * @see RequestMapping - */ -@Target({ElementType.ANNOTATION_TYPE}) -@Retention(RetentionPolicy.RUNTIME) -public @interface Mapping { - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.web.bind.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Meta annotation that indicates a web mapping annotation. + * + * @author Juergen Hoeller + * @since 3.0 + * @see RequestMapping + */ +@Target({ElementType.ANNOTATION_TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface Mapping { + +} diff --git a/org.springframework.web/src/main/java/org/springframework/web/bind/annotation/ValueConstants.java b/org.springframework.web/src/main/java/org/springframework/web/bind/annotation/ValueConstants.java index e7f9c1a132d..a5095f296e3 100644 --- a/org.springframework.web/src/main/java/org/springframework/web/bind/annotation/ValueConstants.java +++ b/org.springframework.web/src/main/java/org/springframework/web/bind/annotation/ValueConstants.java @@ -1,38 +1,38 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.bind.annotation; - -/** - * Common value constants shared between bind annotations. - * - * @author Juergen Hoeller - * @since 3.0.1 - */ -public interface ValueConstants { - - /** - * Constant defining a value for no default - as a replacement for - * <code>null</code> which we cannot use in annotation attributes. - * <p>This is an artificial arrangement of 16 unicode characters, - * with its sole purpose being to never match user-declared values. - * @see RequestParam#defaultValue() - * @see RequestHeader#defaultValue() - * @see CookieValue#defaultValue() - */ - String DEFAULT_NONE = "\n\t\t\n\t\t\n\uE000\uE001\uE002\n\t\t\t\t\n"; - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.web.bind.annotation; + +/** + * Common value constants shared between bind annotations. + * + * @author Juergen Hoeller + * @since 3.0.1 + */ +public interface ValueConstants { + + /** + * Constant defining a value for no default - as a replacement for + * <code>null</code> which we cannot use in annotation attributes. + * <p>This is an artificial arrangement of 16 unicode characters, + * with its sole purpose being to never match user-declared values. + * @see RequestParam#defaultValue() + * @see RequestHeader#defaultValue() + * @see CookieValue#defaultValue() + */ + String DEFAULT_NONE = "\n\t\t\n\t\t\n\uE000\uE001\uE002\n\t\t\t\t\n"; + +} diff --git a/org.springframework.web/src/main/java/org/springframework/web/context/ContextCleanupListener.java b/org.springframework.web/src/main/java/org/springframework/web/context/ContextCleanupListener.java index 71db226277a..4dc269a1b42 100644 --- a/org.springframework.web/src/main/java/org/springframework/web/context/ContextCleanupListener.java +++ b/org.springframework.web/src/main/java/org/springframework/web/context/ContextCleanupListener.java @@ -1,77 +1,77 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.context; - -import java.util.Enumeration; -import javax.servlet.ServletContext; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.factory.DisposableBean; - -/** - * Web application listener that cleans up remaining disposable attributes - * in the ServletContext, i.e. attributes which implement {@link DisposableBean} - * and haven't been removed before. This is typically used for destroying objects - * in "application" scope, for which the lifecycle implies destruction at the - * very end of the web application's shutdown phase. - * - * @author Juergen Hoeller - * @since 3.0 - * @see org.springframework.web.context.support.ServletContextScope - * @see ContextLoaderListener - */ -public class ContextCleanupListener implements ServletContextListener { - - private static final Log logger = LogFactory.getLog(ContextCleanupListener.class); - - - public void contextInitialized(ServletContextEvent event) { - } - - public void contextDestroyed(ServletContextEvent event) { - cleanupAttributes(event.getServletContext()); - } - - - /** - * Find all ServletContext attributes which implement {@link DisposableBean} - * and destroy them, removing all affected ServletContext attributes eventually. - * @param sc the ServletContext to check - */ - static void cleanupAttributes(ServletContext sc) { - Enumeration attrNames = sc.getAttributeNames(); - while (attrNames.hasMoreElements()) { - String attrName = (String) attrNames.nextElement(); - if (attrName.startsWith("org.springframework.")) { - Object attrValue = sc.getAttribute(attrName); - if (attrValue instanceof DisposableBean) { - try { - ((DisposableBean) attrValue).destroy(); - } - catch (Throwable ex) { - logger.error("Couldn't invoke destroy method of attribute with name '" + attrName + "'", ex); - } - } - } - } - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.web.context; + +import java.util.Enumeration; +import javax.servlet.ServletContext; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.springframework.beans.factory.DisposableBean; + +/** + * Web application listener that cleans up remaining disposable attributes + * in the ServletContext, i.e. attributes which implement {@link DisposableBean} + * and haven't been removed before. This is typically used for destroying objects + * in "application" scope, for which the lifecycle implies destruction at the + * very end of the web application's shutdown phase. + * + * @author Juergen Hoeller + * @since 3.0 + * @see org.springframework.web.context.support.ServletContextScope + * @see ContextLoaderListener + */ +public class ContextCleanupListener implements ServletContextListener { + + private static final Log logger = LogFactory.getLog(ContextCleanupListener.class); + + + public void contextInitialized(ServletContextEvent event) { + } + + public void contextDestroyed(ServletContextEvent event) { + cleanupAttributes(event.getServletContext()); + } + + + /** + * Find all ServletContext attributes which implement {@link DisposableBean} + * and destroy them, removing all affected ServletContext attributes eventually. + * @param sc the ServletContext to check + */ + static void cleanupAttributes(ServletContext sc) { + Enumeration attrNames = sc.getAttributeNames(); + while (attrNames.hasMoreElements()) { + String attrName = (String) attrNames.nextElement(); + if (attrName.startsWith("org.springframework.")) { + Object attrValue = sc.getAttribute(attrName); + if (attrValue instanceof DisposableBean) { + try { + ((DisposableBean) attrValue).destroy(); + } + catch (Throwable ex) { + logger.error("Couldn't invoke destroy method of attribute with name '" + attrName + "'", ex); + } + } + } + } + } + +} diff --git a/org.springframework.web/src/main/java/org/springframework/web/context/request/DestructionCallbackBindingListener.java b/org.springframework.web/src/main/java/org/springframework/web/context/request/DestructionCallbackBindingListener.java index 2c64b07901e..04789512aa0 100644 --- a/org.springframework.web/src/main/java/org/springframework/web/context/request/DestructionCallbackBindingListener.java +++ b/org.springframework.web/src/main/java/org/springframework/web/context/request/DestructionCallbackBindingListener.java @@ -1,54 +1,54 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.context.request; - -import java.io.Serializable; -import javax.servlet.http.HttpSessionBindingEvent; -import javax.servlet.http.HttpSessionBindingListener; - -/** - * Adapter that implements the Servlet 2.3 HttpSessionBindingListener - * interface, wrapping a session destruction callback. - * - * @author Juergen Hoeller - * @since 3.0 - * @see RequestAttributes#registerDestructionCallback - * @see ServletRequestAttributes#registerSessionDestructionCallback - */ -public class DestructionCallbackBindingListener implements HttpSessionBindingListener, Serializable { - - private final Runnable destructionCallback; - - - /** - * Create a new DestructionCallbackBindingListener for the given callback. - * @param destructionCallback the Runnable to execute when this listener - * object gets unbound from the session - */ - public DestructionCallbackBindingListener(Runnable destructionCallback) { - this.destructionCallback = destructionCallback; - } - - - public void valueBound(HttpSessionBindingEvent event) { - } - - public void valueUnbound(HttpSessionBindingEvent event) { - this.destructionCallback.run(); - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.web.context.request; + +import java.io.Serializable; +import javax.servlet.http.HttpSessionBindingEvent; +import javax.servlet.http.HttpSessionBindingListener; + +/** + * Adapter that implements the Servlet 2.3 HttpSessionBindingListener + * interface, wrapping a session destruction callback. + * + * @author Juergen Hoeller + * @since 3.0 + * @see RequestAttributes#registerDestructionCallback + * @see ServletRequestAttributes#registerSessionDestructionCallback + */ +public class DestructionCallbackBindingListener implements HttpSessionBindingListener, Serializable { + + private final Runnable destructionCallback; + + + /** + * Create a new DestructionCallbackBindingListener for the given callback. + * @param destructionCallback the Runnable to execute when this listener + * object gets unbound from the session + */ + public DestructionCallbackBindingListener(Runnable destructionCallback) { + this.destructionCallback = destructionCallback; + } + + + public void valueBound(HttpSessionBindingEvent event) { + } + + public void valueUnbound(HttpSessionBindingEvent event) { + this.destructionCallback.run(); + } + +} diff --git a/org.springframework.web/src/main/java/org/springframework/web/context/support/ServletContextScope.java b/org.springframework.web/src/main/java/org/springframework/web/context/support/ServletContextScope.java index a4cc9fc814c..90301719e46 100644 --- a/org.springframework.web/src/main/java/org/springframework/web/context/support/ServletContextScope.java +++ b/org.springframework.web/src/main/java/org/springframework/web/context/support/ServletContextScope.java @@ -1,111 +1,111 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.context.support; - -import java.util.LinkedHashMap; -import java.util.Map; -import javax.servlet.ServletContext; - -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.ObjectFactory; -import org.springframework.beans.factory.config.Scope; -import org.springframework.util.Assert; - -/** - * {@link Scope} wrapper for a ServletContext, i.e. for global web application attributes. - * - * <p>This differs from traditional Spring singletons in that it exposes attributes in the - * ServletContext. Those attributes will get destroyed whenever the entire application - * shuts down, which might be earlier or later than the shutdown of the containing Spring - * ApplicationContext. - * - * <p>The associated destruction mechanism relies on a - * {@link org.springframework.web.context.ContextCleanupListener} being registered in - * <code>web.xml</code>. Note that {@link org.springframework.web.context.ContextLoaderListener} - * includes ContextCleanupListener's functionality. - * - * <p>This scope is registered as default scope with key - * {@link org.springframework.web.context.WebApplicationContext#SCOPE_APPLICATION "application"}. - * - * @author Juergen Hoeller - * @since 3.0 - * @see org.springframework.web.context.ContextCleanupListener - */ -public class ServletContextScope implements Scope, DisposableBean { - - private final ServletContext servletContext; - - private final Map<String, Runnable> destructionCallbacks = new LinkedHashMap<String, Runnable>(); - - - /** - * Create a new Scope wrapper for the given ServletContext. - * @param servletContext the ServletContext to wrap - */ - public ServletContextScope(ServletContext servletContext) { - Assert.notNull(servletContext, "ServletContext must not be null"); - this.servletContext = servletContext; - } - - - public Object get(String name, ObjectFactory<?> objectFactory) { - Object scopedObject = this.servletContext.getAttribute(name); - if (scopedObject == null) { - scopedObject = objectFactory.getObject(); - this.servletContext.setAttribute(name, scopedObject); - } - return scopedObject; - } - - public Object remove(String name) { - Object scopedObject = this.servletContext.getAttribute(name); - if (scopedObject != null) { - this.servletContext.removeAttribute(name); - this.destructionCallbacks.remove(name); - return scopedObject; - } - else { - return null; - } - } - - public void registerDestructionCallback(String name, Runnable callback) { - this.destructionCallbacks.put(name, callback); - } - - public Object resolveContextualObject(String key) { - return null; - } - - public String getConversationId() { - return null; - } - - - /** - * Invoke all registered destruction callbacks. - * To be called on ServletContext shutdown. - * @see org.springframework.web.context.ContextCleanupListener - */ - public void destroy() { - for (Runnable runnable : this.destructionCallbacks.values()) { - runnable.run(); - } - this.destructionCallbacks.clear(); - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.web.context.support; + +import java.util.LinkedHashMap; +import java.util.Map; +import javax.servlet.ServletContext; + +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.ObjectFactory; +import org.springframework.beans.factory.config.Scope; +import org.springframework.util.Assert; + +/** + * {@link Scope} wrapper for a ServletContext, i.e. for global web application attributes. + * + * <p>This differs from traditional Spring singletons in that it exposes attributes in the + * ServletContext. Those attributes will get destroyed whenever the entire application + * shuts down, which might be earlier or later than the shutdown of the containing Spring + * ApplicationContext. + * + * <p>The associated destruction mechanism relies on a + * {@link org.springframework.web.context.ContextCleanupListener} being registered in + * <code>web.xml</code>. Note that {@link org.springframework.web.context.ContextLoaderListener} + * includes ContextCleanupListener's functionality. + * + * <p>This scope is registered as default scope with key + * {@link org.springframework.web.context.WebApplicationContext#SCOPE_APPLICATION "application"}. + * + * @author Juergen Hoeller + * @since 3.0 + * @see org.springframework.web.context.ContextCleanupListener + */ +public class ServletContextScope implements Scope, DisposableBean { + + private final ServletContext servletContext; + + private final Map<String, Runnable> destructionCallbacks = new LinkedHashMap<String, Runnable>(); + + + /** + * Create a new Scope wrapper for the given ServletContext. + * @param servletContext the ServletContext to wrap + */ + public ServletContextScope(ServletContext servletContext) { + Assert.notNull(servletContext, "ServletContext must not be null"); + this.servletContext = servletContext; + } + + + public Object get(String name, ObjectFactory<?> objectFactory) { + Object scopedObject = this.servletContext.getAttribute(name); + if (scopedObject == null) { + scopedObject = objectFactory.getObject(); + this.servletContext.setAttribute(name, scopedObject); + } + return scopedObject; + } + + public Object remove(String name) { + Object scopedObject = this.servletContext.getAttribute(name); + if (scopedObject != null) { + this.servletContext.removeAttribute(name); + this.destructionCallbacks.remove(name); + return scopedObject; + } + else { + return null; + } + } + + public void registerDestructionCallback(String name, Runnable callback) { + this.destructionCallbacks.put(name, callback); + } + + public Object resolveContextualObject(String key) { + return null; + } + + public String getConversationId() { + return null; + } + + + /** + * Invoke all registered destruction callbacks. + * To be called on ServletContext shutdown. + * @see org.springframework.web.context.ContextCleanupListener + */ + public void destroy() { + for (Runnable runnable : this.destructionCallbacks.values()) { + runnable.run(); + } + this.destructionCallbacks.clear(); + } + +} diff --git a/org.springframework.web/src/main/java/org/springframework/web/method/annotation/package-info.java b/org.springframework.web/src/main/java/org/springframework/web/method/annotation/package-info.java index db95fbe4a38..43712dbba53 100644 --- a/org.springframework.web/src/main/java/org/springframework/web/method/annotation/package-info.java +++ b/org.springframework.web/src/main/java/org/springframework/web/method/annotation/package-info.java @@ -1,8 +1,8 @@ - -/** - * - * Support classes for annotation-based handler method processing. - * - */ -package org.springframework.web.method.annotation; - + +/** + * + * Support classes for annotation-based handler method processing. + * + */ +package org.springframework.web.method.annotation; + diff --git a/org.springframework.web/src/main/java/org/springframework/web/method/support/package-info.java b/org.springframework.web/src/main/java/org/springframework/web/method/support/package-info.java index ee561dd1f33..1de7c0ed275 100644 --- a/org.springframework.web/src/main/java/org/springframework/web/method/support/package-info.java +++ b/org.springframework.web/src/main/java/org/springframework/web/method/support/package-info.java @@ -1,8 +1,8 @@ - -/** - * - * Generic support classes for handler method processing. - * - */ -package org.springframework.web.method.support; - + +/** + * + * Generic support classes for handler method processing. + * + */ +package org.springframework.web.method.support; + diff --git a/org.springframework.web/src/main/java/org/springframework/web/multipart/support/StandardMultipartHttpServletRequest.java b/org.springframework.web/src/main/java/org/springframework/web/multipart/support/StandardMultipartHttpServletRequest.java index 6e7b7e641c3..099a6bb249c 100644 --- a/org.springframework.web/src/main/java/org/springframework/web/multipart/support/StandardMultipartHttpServletRequest.java +++ b/org.springframework.web/src/main/java/org/springframework/web/multipart/support/StandardMultipartHttpServletRequest.java @@ -1,175 +1,175 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.multipart.support; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Collection; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.Part; - -import org.springframework.http.HttpHeaders; -import org.springframework.util.FileCopyUtils; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.web.multipart.MultipartException; -import org.springframework.web.multipart.MultipartFile; - -/** - * Spring MultipartHttpServletRequest adapter, wrapping a Servlet 3.0 HttpServletRequest - * and its Part objects. Parameters get exposed through the native request's getParameter - * methods - without any custom processing on our side. - * - * @author Juergen Hoeller - * @since 3.1 - */ -public class StandardMultipartHttpServletRequest extends AbstractMultipartHttpServletRequest { - - private static final String CONTENT_DISPOSITION = "Content-Disposition"; - - private static final String FILENAME_KEY = "filename="; - - - /** - * Create a new StandardMultipartHttpServletRequest wrapper for the given request. - * @param request the servlet request to wrap - * @throws MultipartException if parsing failed - */ - public StandardMultipartHttpServletRequest(HttpServletRequest request) throws MultipartException { - super(request); - try { - Collection<Part> parts = request.getParts(); - MultiValueMap<String, MultipartFile> files = new LinkedMultiValueMap<String, MultipartFile>(parts.size()); - for (Part part : parts) { - String filename = extractFilename(part.getHeader(CONTENT_DISPOSITION)); - if (filename != null) { - files.add(part.getName(), new StandardMultipartFile(part, filename)); - } - } - setMultipartFiles(files); - } - catch (Exception ex) { - throw new MultipartException("Could not parse multipart servlet request", ex); - } - } - - private String extractFilename(String contentDisposition) { - if (contentDisposition == null) { - return null; - } - // TODO: can only handle the typical case at the moment - int startIndex = contentDisposition.indexOf(FILENAME_KEY); - if (startIndex == -1) { - return null; - } - String filename = contentDisposition.substring(startIndex + FILENAME_KEY.length()); - if (filename.startsWith("\"")) { - int endIndex = filename.indexOf("\"", 1); - if (endIndex != -1) { - return filename.substring(1, endIndex); - } - } - else { - int endIndex = filename.indexOf(";"); - if (endIndex != -1) { - return filename.substring(0, endIndex); - } - } - return filename; - } - - - public String getMultipartContentType(String paramOrFileName) { - try { - Part part = getPart(paramOrFileName); - return (part != null ? part.getContentType() : null); - } - catch (Exception ex) { - throw new MultipartException("Could not access multipart servlet request", ex); - } - } - - public HttpHeaders getMultipartHeaders(String paramOrFileName) { - try { - Part part = getPart(paramOrFileName); - if (part != null) { - HttpHeaders headers = new HttpHeaders(); - for (String headerName : part.getHeaderNames()) { - headers.put(headerName, new ArrayList<String>(part.getHeaders(headerName))); - } - return headers; - } - else { - return null; - } - } - catch (Exception ex) { - throw new MultipartException("Could not access multipart servlet request", ex); - } - } - - - /** - * Spring MultipartFile adapter, wrapping a Servlet 3.0 Part object. - */ - private static class StandardMultipartFile implements MultipartFile { - - private final Part part; - - private final String filename; - - public StandardMultipartFile(Part part, String filename) { - this.part = part; - this.filename = filename; - } - - public String getName() { - return this.part.getName(); - } - - public String getOriginalFilename() { - return this.filename; - } - - public String getContentType() { - return this.part.getContentType(); - } - - public boolean isEmpty() { - return (this.part.getSize() == 0); - } - - public long getSize() { - return this.part.getSize(); - } - - public byte[] getBytes() throws IOException { - return FileCopyUtils.copyToByteArray(this.part.getInputStream()); - } - - public InputStream getInputStream() throws IOException { - return this.part.getInputStream(); - } - - public void transferTo(File dest) throws IOException, IllegalStateException { - this.part.write(dest.getPath()); - } - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.web.multipart.support; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collection; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.Part; + +import org.springframework.http.HttpHeaders; +import org.springframework.util.FileCopyUtils; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.multipart.MultipartException; +import org.springframework.web.multipart.MultipartFile; + +/** + * Spring MultipartHttpServletRequest adapter, wrapping a Servlet 3.0 HttpServletRequest + * and its Part objects. Parameters get exposed through the native request's getParameter + * methods - without any custom processing on our side. + * + * @author Juergen Hoeller + * @since 3.1 + */ +public class StandardMultipartHttpServletRequest extends AbstractMultipartHttpServletRequest { + + private static final String CONTENT_DISPOSITION = "Content-Disposition"; + + private static final String FILENAME_KEY = "filename="; + + + /** + * Create a new StandardMultipartHttpServletRequest wrapper for the given request. + * @param request the servlet request to wrap + * @throws MultipartException if parsing failed + */ + public StandardMultipartHttpServletRequest(HttpServletRequest request) throws MultipartException { + super(request); + try { + Collection<Part> parts = request.getParts(); + MultiValueMap<String, MultipartFile> files = new LinkedMultiValueMap<String, MultipartFile>(parts.size()); + for (Part part : parts) { + String filename = extractFilename(part.getHeader(CONTENT_DISPOSITION)); + if (filename != null) { + files.add(part.getName(), new StandardMultipartFile(part, filename)); + } + } + setMultipartFiles(files); + } + catch (Exception ex) { + throw new MultipartException("Could not parse multipart servlet request", ex); + } + } + + private String extractFilename(String contentDisposition) { + if (contentDisposition == null) { + return null; + } + // TODO: can only handle the typical case at the moment + int startIndex = contentDisposition.indexOf(FILENAME_KEY); + if (startIndex == -1) { + return null; + } + String filename = contentDisposition.substring(startIndex + FILENAME_KEY.length()); + if (filename.startsWith("\"")) { + int endIndex = filename.indexOf("\"", 1); + if (endIndex != -1) { + return filename.substring(1, endIndex); + } + } + else { + int endIndex = filename.indexOf(";"); + if (endIndex != -1) { + return filename.substring(0, endIndex); + } + } + return filename; + } + + + public String getMultipartContentType(String paramOrFileName) { + try { + Part part = getPart(paramOrFileName); + return (part != null ? part.getContentType() : null); + } + catch (Exception ex) { + throw new MultipartException("Could not access multipart servlet request", ex); + } + } + + public HttpHeaders getMultipartHeaders(String paramOrFileName) { + try { + Part part = getPart(paramOrFileName); + if (part != null) { + HttpHeaders headers = new HttpHeaders(); + for (String headerName : part.getHeaderNames()) { + headers.put(headerName, new ArrayList<String>(part.getHeaders(headerName))); + } + return headers; + } + else { + return null; + } + } + catch (Exception ex) { + throw new MultipartException("Could not access multipart servlet request", ex); + } + } + + + /** + * Spring MultipartFile adapter, wrapping a Servlet 3.0 Part object. + */ + private static class StandardMultipartFile implements MultipartFile { + + private final Part part; + + private final String filename; + + public StandardMultipartFile(Part part, String filename) { + this.part = part; + this.filename = filename; + } + + public String getName() { + return this.part.getName(); + } + + public String getOriginalFilename() { + return this.filename; + } + + public String getContentType() { + return this.part.getContentType(); + } + + public boolean isEmpty() { + return (this.part.getSize() == 0); + } + + public long getSize() { + return this.part.getSize(); + } + + public byte[] getBytes() throws IOException { + return FileCopyUtils.copyToByteArray(this.part.getInputStream()); + } + + public InputStream getInputStream() throws IOException { + return this.part.getInputStream(); + } + + public void transferTo(File dest) throws IOException, IllegalStateException { + this.part.write(dest.getPath()); + } + } + +} diff --git a/org.springframework.web/src/main/java/org/springframework/web/multipart/support/StandardServletMultipartResolver.java b/org.springframework.web/src/main/java/org/springframework/web/multipart/support/StandardServletMultipartResolver.java index 539c78c965f..7356345aead 100644 --- a/org.springframework.web/src/main/java/org/springframework/web/multipart/support/StandardServletMultipartResolver.java +++ b/org.springframework.web/src/main/java/org/springframework/web/multipart/support/StandardServletMultipartResolver.java @@ -1,73 +1,73 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.multipart.support; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.Part; - -import org.apache.commons.logging.LogFactory; - -import org.springframework.web.multipart.MultipartException; -import org.springframework.web.multipart.MultipartHttpServletRequest; -import org.springframework.web.multipart.MultipartResolver; - -/** - * Standard implementation of the {@link MultipartResolver} interface, - * based on the Servlet 3.0 {@link javax.servlet.http.Part} API. - * To be added as "multipartResolver" bean to a Spring DispatcherServlet context, - * without any extra configuration at the bean level (see below). - * - * <p><b>Note:</b> In order to use Servlet 3.0 based multipart parsing, - * you need to mark the affected servlet with a "multipart-config" section in - * <code>web.xml</code>, or with a {@link javax.servlet.MultipartConfigElement} - * in programmatic servlet registration, or (in case of a custom servlet class) - * possibly with a {@link javax.servlet.annotation.MultipartConfig} annotation - * on your servlet class. Configuration settings such as maximum sizes or - * storage locations need to be applied at that servlet registration level; - * Servlet 3.0 does not allow for them to be set at the MultipartResolver level. - * - * @author Juergen Hoeller - * @since 3.1 - */ -public class StandardServletMultipartResolver implements MultipartResolver { - - public boolean isMultipart(HttpServletRequest request) { - // Same check as in Commons FileUpload... - if (!"post".equals(request.getMethod().toLowerCase())) { - return false; - } - String contentType = request.getContentType(); - return (contentType != null && contentType.toLowerCase().startsWith("multipart/")); - } - - public MultipartHttpServletRequest resolveMultipart(HttpServletRequest request) throws MultipartException { - return new StandardMultipartHttpServletRequest(request); - } - - public void cleanupMultipart(MultipartHttpServletRequest request) { - // To be on the safe side: explicitly delete all parts. - try { - for (Part part : request.getParts()) { - part.delete(); - } - } - catch (Exception ex) { - LogFactory.getLog(getClass()).warn("Failed to perform cleanup of multipart items", ex); - } - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.web.multipart.support; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.Part; + +import org.apache.commons.logging.LogFactory; + +import org.springframework.web.multipart.MultipartException; +import org.springframework.web.multipart.MultipartHttpServletRequest; +import org.springframework.web.multipart.MultipartResolver; + +/** + * Standard implementation of the {@link MultipartResolver} interface, + * based on the Servlet 3.0 {@link javax.servlet.http.Part} API. + * To be added as "multipartResolver" bean to a Spring DispatcherServlet context, + * without any extra configuration at the bean level (see below). + * + * <p><b>Note:</b> In order to use Servlet 3.0 based multipart parsing, + * you need to mark the affected servlet with a "multipart-config" section in + * <code>web.xml</code>, or with a {@link javax.servlet.MultipartConfigElement} + * in programmatic servlet registration, or (in case of a custom servlet class) + * possibly with a {@link javax.servlet.annotation.MultipartConfig} annotation + * on your servlet class. Configuration settings such as maximum sizes or + * storage locations need to be applied at that servlet registration level; + * Servlet 3.0 does not allow for them to be set at the MultipartResolver level. + * + * @author Juergen Hoeller + * @since 3.1 + */ +public class StandardServletMultipartResolver implements MultipartResolver { + + public boolean isMultipart(HttpServletRequest request) { + // Same check as in Commons FileUpload... + if (!"post".equals(request.getMethod().toLowerCase())) { + return false; + } + String contentType = request.getContentType(); + return (contentType != null && contentType.toLowerCase().startsWith("multipart/")); + } + + public MultipartHttpServletRequest resolveMultipart(HttpServletRequest request) throws MultipartException { + return new StandardMultipartHttpServletRequest(request); + } + + public void cleanupMultipart(MultipartHttpServletRequest request) { + // To be on the safe side: explicitly delete all parts. + try { + for (Part part : request.getParts()) { + part.delete(); + } + } + catch (Exception ex) { + LogFactory.getLog(getClass()).warn("Failed to perform cleanup of multipart items", ex); + } + } + +} diff --git a/org.springframework.web/src/test/java/org/springframework/mock/web/DelegatingServletInputStream.java b/org.springframework.web/src/test/java/org/springframework/mock/web/DelegatingServletInputStream.java index 22dd38281ea..b083e95b27e 100644 --- a/org.springframework.web/src/test/java/org/springframework/mock/web/DelegatingServletInputStream.java +++ b/org.springframework.web/src/test/java/org/springframework/mock/web/DelegatingServletInputStream.java @@ -1,66 +1,66 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.mock.web; - -import java.io.IOException; -import java.io.InputStream; -import javax.servlet.ServletInputStream; - -import org.springframework.util.Assert; - -/** - * Delegating implementation of {@link javax.servlet.ServletInputStream}. - * - * <p>Used by {@link MockHttpServletRequest}; typically not directly - * used for testing application controllers. - * - * @author Juergen Hoeller - * @since 1.0.2 - * @see MockHttpServletRequest - */ -public class DelegatingServletInputStream extends ServletInputStream { - - private final InputStream sourceStream; - - - /** - * Create a DelegatingServletInputStream for the given source stream. - * @param sourceStream the source stream (never <code>null</code>) - */ - public DelegatingServletInputStream(InputStream sourceStream) { - Assert.notNull(sourceStream, "Source InputStream must not be null"); - this.sourceStream = sourceStream; - } - - /** - * Return the underlying source stream (never <code>null</code>). - */ - public final InputStream getSourceStream() { - return this.sourceStream; - } - - - public int read() throws IOException { - return this.sourceStream.read(); - } - - public void close() throws IOException { - super.close(); - this.sourceStream.close(); - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.mock.web; + +import java.io.IOException; +import java.io.InputStream; +import javax.servlet.ServletInputStream; + +import org.springframework.util.Assert; + +/** + * Delegating implementation of {@link javax.servlet.ServletInputStream}. + * + * <p>Used by {@link MockHttpServletRequest}; typically not directly + * used for testing application controllers. + * + * @author Juergen Hoeller + * @since 1.0.2 + * @see MockHttpServletRequest + */ +public class DelegatingServletInputStream extends ServletInputStream { + + private final InputStream sourceStream; + + + /** + * Create a DelegatingServletInputStream for the given source stream. + * @param sourceStream the source stream (never <code>null</code>) + */ + public DelegatingServletInputStream(InputStream sourceStream) { + Assert.notNull(sourceStream, "Source InputStream must not be null"); + this.sourceStream = sourceStream; + } + + /** + * Return the underlying source stream (never <code>null</code>). + */ + public final InputStream getSourceStream() { + return this.sourceStream; + } + + + public int read() throws IOException { + return this.sourceStream.read(); + } + + public void close() throws IOException { + super.close(); + this.sourceStream.close(); + } + +} diff --git a/org.springframework.web/src/test/java/org/springframework/mock/web/DelegatingServletOutputStream.java b/org.springframework.web/src/test/java/org/springframework/mock/web/DelegatingServletOutputStream.java index 094391ae7d3..66fca5df2f9 100644 --- a/org.springframework.web/src/test/java/org/springframework/mock/web/DelegatingServletOutputStream.java +++ b/org.springframework.web/src/test/java/org/springframework/mock/web/DelegatingServletOutputStream.java @@ -1,71 +1,71 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.mock.web; - -import java.io.IOException; -import java.io.OutputStream; -import javax.servlet.ServletOutputStream; - -import org.springframework.util.Assert; - -/** - * Delegating implementation of {@link javax.servlet.ServletOutputStream}. - * - * <p>Used by {@link MockHttpServletResponse}; typically not directly - * used for testing application controllers. - * - * @author Juergen Hoeller - * @since 1.0.2 - * @see MockHttpServletResponse - */ -public class DelegatingServletOutputStream extends ServletOutputStream { - - private final OutputStream targetStream; - - - /** - * Create a DelegatingServletOutputStream for the given target stream. - * @param targetStream the target stream (never <code>null</code>) - */ - public DelegatingServletOutputStream(OutputStream targetStream) { - Assert.notNull(targetStream, "Target OutputStream must not be null"); - this.targetStream = targetStream; - } - - /** - * Return the underlying target stream (never <code>null</code>). - */ - public final OutputStream getTargetStream() { - return this.targetStream; - } - - - public void write(int b) throws IOException { - this.targetStream.write(b); - } - - public void flush() throws IOException { - super.flush(); - this.targetStream.flush(); - } - - public void close() throws IOException { - super.close(); - this.targetStream.close(); - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.mock.web; + +import java.io.IOException; +import java.io.OutputStream; +import javax.servlet.ServletOutputStream; + +import org.springframework.util.Assert; + +/** + * Delegating implementation of {@link javax.servlet.ServletOutputStream}. + * + * <p>Used by {@link MockHttpServletResponse}; typically not directly + * used for testing application controllers. + * + * @author Juergen Hoeller + * @since 1.0.2 + * @see MockHttpServletResponse + */ +public class DelegatingServletOutputStream extends ServletOutputStream { + + private final OutputStream targetStream; + + + /** + * Create a DelegatingServletOutputStream for the given target stream. + * @param targetStream the target stream (never <code>null</code>) + */ + public DelegatingServletOutputStream(OutputStream targetStream) { + Assert.notNull(targetStream, "Target OutputStream must not be null"); + this.targetStream = targetStream; + } + + /** + * Return the underlying target stream (never <code>null</code>). + */ + public final OutputStream getTargetStream() { + return this.targetStream; + } + + + public void write(int b) throws IOException { + this.targetStream.write(b); + } + + public void flush() throws IOException { + super.flush(); + this.targetStream.flush(); + } + + public void close() throws IOException { + super.close(); + this.targetStream.close(); + } + +} diff --git a/org.springframework.web/src/test/java/org/springframework/mock/web/HeaderValueHolder.java b/org.springframework.web/src/test/java/org/springframework/mock/web/HeaderValueHolder.java index 48224a00d21..afe74ad8f0f 100644 --- a/org.springframework.web/src/test/java/org/springframework/mock/web/HeaderValueHolder.java +++ b/org.springframework.web/src/test/java/org/springframework/mock/web/HeaderValueHolder.java @@ -1,96 +1,96 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.mock.web; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import org.springframework.util.Assert; -import org.springframework.util.CollectionUtils; - -/** - * Internal helper class that serves as value holder for request headers. - * - * @author Juergen Hoeller - * @author Rick Evans - * @since 2.0.1 - */ -class HeaderValueHolder { - - private final List<Object> values = new LinkedList<Object>(); - - - public void setValue(Object value) { - this.values.clear(); - this.values.add(value); - } - - public void addValue(Object value) { - this.values.add(value); - } - - public void addValues(Collection<?> values) { - this.values.addAll(values); - } - - public void addValueArray(Object values) { - CollectionUtils.mergeArrayIntoCollection(values, this.values); - } - - public List<Object> getValues() { - return Collections.unmodifiableList(this.values); - } - - public List<String> getStringValues() { - List<String> stringList = new ArrayList<String>(this.values.size()); - for (Object value : this.values) { - stringList.add(value.toString()); - } - return Collections.unmodifiableList(stringList); - } - - public Object getValue() { - return (!this.values.isEmpty() ? this.values.get(0) : null); - } - - public String getStringValue() { - return (!this.values.isEmpty() ? this.values.get(0).toString() : null); - } - - - /** - * Find a HeaderValueHolder by name, ignoring casing. - * @param headers the Map of header names to HeaderValueHolders - * @param name the name of the desired header - * @return the corresponding HeaderValueHolder, - * or <code>null</code> if none found - */ - public static HeaderValueHolder getByName(Map<String, HeaderValueHolder> headers, String name) { - Assert.notNull(name, "Header name must not be null"); - for (String headerName : headers.keySet()) { - if (headerName.equalsIgnoreCase(name)) { - return headers.get(headerName); - } - } - return null; - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.mock.web; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; + +/** + * Internal helper class that serves as value holder for request headers. + * + * @author Juergen Hoeller + * @author Rick Evans + * @since 2.0.1 + */ +class HeaderValueHolder { + + private final List<Object> values = new LinkedList<Object>(); + + + public void setValue(Object value) { + this.values.clear(); + this.values.add(value); + } + + public void addValue(Object value) { + this.values.add(value); + } + + public void addValues(Collection<?> values) { + this.values.addAll(values); + } + + public void addValueArray(Object values) { + CollectionUtils.mergeArrayIntoCollection(values, this.values); + } + + public List<Object> getValues() { + return Collections.unmodifiableList(this.values); + } + + public List<String> getStringValues() { + List<String> stringList = new ArrayList<String>(this.values.size()); + for (Object value : this.values) { + stringList.add(value.toString()); + } + return Collections.unmodifiableList(stringList); + } + + public Object getValue() { + return (!this.values.isEmpty() ? this.values.get(0) : null); + } + + public String getStringValue() { + return (!this.values.isEmpty() ? this.values.get(0).toString() : null); + } + + + /** + * Find a HeaderValueHolder by name, ignoring casing. + * @param headers the Map of header names to HeaderValueHolders + * @param name the name of the desired header + * @return the corresponding HeaderValueHolder, + * or <code>null</code> if none found + */ + public static HeaderValueHolder getByName(Map<String, HeaderValueHolder> headers, String name) { + Assert.notNull(name, "Header name must not be null"); + for (String headerName : headers.keySet()) { + if (headerName.equalsIgnoreCase(name)) { + return headers.get(headerName); + } + } + return null; + } + +} diff --git a/org.springframework.web/src/test/java/org/springframework/mock/web/MockHttpServletRequest.java b/org.springframework.web/src/test/java/org/springframework/mock/web/MockHttpServletRequest.java index f493d553cf1..5d23662a3fc 100644 --- a/org.springframework.web/src/test/java/org/springframework/mock/web/MockHttpServletRequest.java +++ b/org.springframework.web/src/test/java/org/springframework/mock/web/MockHttpServletRequest.java @@ -1,948 +1,948 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.mock.web; - -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.io.UnsupportedEncodingException; -import java.security.Principal; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; - -import javax.servlet.AsyncContext; -import javax.servlet.DispatcherType; -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletInputStream; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; -import javax.servlet.http.Part; - -import org.springframework.util.Assert; -import org.springframework.util.LinkedCaseInsensitiveMap; - -/** - * Mock implementation of the {@link javax.servlet.http.HttpServletRequest} - * interface. Supports the Servlet 2.5 API level; throws - * {@link UnsupportedOperationException} for all methods introduced in Servlet 3.0. - * - * <p>Used for testing the web framework; also useful for testing - * application controllers. - * - * @author Juergen Hoeller - * @author Rod Johnson - * @author Rick Evans - * @author Mark Fisher - * @author Chris Beams - * @since 1.0.2 - */ -public class MockHttpServletRequest implements HttpServletRequest { - - /** - * The default protocol: 'http'. - */ - public static final String DEFAULT_PROTOCOL = "http"; - - /** - * The default server address: '127.0.0.1'. - */ - public static final String DEFAULT_SERVER_ADDR = "127.0.0.1"; - - /** - * The default server name: 'localhost'. - */ - public static final String DEFAULT_SERVER_NAME = "localhost"; - - /** - * The default server port: '80'. - */ - public static final int DEFAULT_SERVER_PORT = 80; - - /** - * The default remote address: '127.0.0.1'. - */ - public static final String DEFAULT_REMOTE_ADDR = "127.0.0.1"; - - /** - * The default remote host: 'localhost'. - */ - public static final String DEFAULT_REMOTE_HOST = "localhost"; - - private static final String CONTENT_TYPE_HEADER = "Content-Type"; - - private static final String CHARSET_PREFIX = "charset="; - - - private boolean active = true; - - - //--------------------------------------------------------------------- - // ServletRequest properties - //--------------------------------------------------------------------- - - private final Map<String, Object> attributes = new LinkedHashMap<String, Object>(); - - private String characterEncoding; - - private byte[] content; - - private String contentType; - - private final Map<String, String[]> parameters = new LinkedHashMap<String, String[]>(16); - - private String protocol = DEFAULT_PROTOCOL; - - private String scheme = DEFAULT_PROTOCOL; - - private String serverName = DEFAULT_SERVER_NAME; - - private int serverPort = DEFAULT_SERVER_PORT; - - private String remoteAddr = DEFAULT_REMOTE_ADDR; - - private String remoteHost = DEFAULT_REMOTE_HOST; - - /** List of locales in descending order */ - private final List<Locale> locales = new LinkedList<Locale>(); - - private boolean secure = false; - - private final ServletContext servletContext; - - private int remotePort = DEFAULT_SERVER_PORT; - - private String localName = DEFAULT_SERVER_NAME; - - private String localAddr = DEFAULT_SERVER_ADDR; - - private int localPort = DEFAULT_SERVER_PORT; - - private Map<String, Part> parts = new HashMap<String, Part>(); - - //--------------------------------------------------------------------- - // HttpServletRequest properties - //--------------------------------------------------------------------- - - private String authType; - - private Cookie[] cookies; - - private final Map<String, HeaderValueHolder> headers = new LinkedCaseInsensitiveMap<HeaderValueHolder>(); - - private String method; - - private String pathInfo; - - private String contextPath = ""; - - private String queryString; - - private String remoteUser; - - private final Set<String> userRoles = new HashSet<String>(); - - private Principal userPrincipal; - - private String requestedSessionId; - - private String requestURI; - - private String servletPath = ""; - - private HttpSession session; - - private boolean requestedSessionIdValid = true; - - private boolean requestedSessionIdFromCookie = true; - - private boolean requestedSessionIdFromURL = false; - - - //--------------------------------------------------------------------- - // Constructors - //--------------------------------------------------------------------- - - /** - * Create a new MockHttpServletRequest with a default - * {@link MockServletContext}. - * @see MockServletContext - */ - public MockHttpServletRequest() { - this(null, "", ""); - } - - /** - * Create a new MockHttpServletRequest with a default - * {@link MockServletContext}. - * @param method the request method (may be <code>null</code>) - * @param requestURI the request URI (may be <code>null</code>) - * @see #setMethod - * @see #setRequestURI - * @see MockServletContext - */ - public MockHttpServletRequest(String method, String requestURI) { - this(null, method, requestURI); - } - - /** - * Create a new MockHttpServletRequest. - * @param servletContext the ServletContext that the request runs in - * (may be <code>null</code> to use a default MockServletContext) - * @see MockServletContext - */ - public MockHttpServletRequest(ServletContext servletContext) { - this(servletContext, "", ""); - } - - /** - * Create a new MockHttpServletRequest. - * @param servletContext the ServletContext that the request runs in - * (may be <code>null</code> to use a default MockServletContext) - * @param method the request method (may be <code>null</code>) - * @param requestURI the request URI (may be <code>null</code>) - * @see #setMethod - * @see #setRequestURI - * @see MockServletContext - */ - public MockHttpServletRequest(ServletContext servletContext, String method, String requestURI) { - this.servletContext = (servletContext != null ? servletContext : new MockServletContext()); - this.method = method; - this.requestURI = requestURI; - this.locales.add(Locale.ENGLISH); - } - - - //--------------------------------------------------------------------- - // Lifecycle methods - //--------------------------------------------------------------------- - - /** - * Return the ServletContext that this request is associated with. - * (Not available in the standard HttpServletRequest interface for some reason.) - */ - public ServletContext getServletContext() { - return this.servletContext; - } - - /** - * Return whether this request is still active (that is, not completed yet). - */ - public boolean isActive() { - return this.active; - } - - /** - * Mark this request as completed, keeping its state. - */ - public void close() { - this.active = false; - } - - /** - * Invalidate this request, clearing its state. - */ - public void invalidate() { - close(); - clearAttributes(); - } - - /** - * Check whether this request is still active (that is, not completed yet), - * throwing an IllegalStateException if not active anymore. - */ - protected void checkActive() throws IllegalStateException { - if (!this.active) { - throw new IllegalStateException("Request is not active anymore"); - } - } - - - //--------------------------------------------------------------------- - // ServletRequest interface - //--------------------------------------------------------------------- - - public Object getAttribute(String name) { - checkActive(); - return this.attributes.get(name); - } - - public Enumeration<String> getAttributeNames() { - checkActive(); - return Collections.enumeration(this.attributes.keySet()); - } - - public String getCharacterEncoding() { - return this.characterEncoding; - } - - public void setCharacterEncoding(String characterEncoding) { - this.characterEncoding = characterEncoding; - updateContentTypeHeader(); - } - - private void updateContentTypeHeader() { - if (this.contentType != null) { - StringBuilder sb = new StringBuilder(this.contentType); - if (this.contentType.toLowerCase().indexOf(CHARSET_PREFIX) == -1 && this.characterEncoding != null) { - sb.append(";").append(CHARSET_PREFIX).append(this.characterEncoding); - } - doAddHeaderValue(CONTENT_TYPE_HEADER, sb.toString(), true); - } - } - - public void setContent(byte[] content) { - this.content = content; - } - - public int getContentLength() { - return (this.content != null ? this.content.length : -1); - } - - public void setContentType(String contentType) { - this.contentType = contentType; - if (contentType != null) { - int charsetIndex = contentType.toLowerCase().indexOf(CHARSET_PREFIX); - if (charsetIndex != -1) { - String encoding = contentType.substring(charsetIndex + CHARSET_PREFIX.length()); - this.characterEncoding = encoding; - } - updateContentTypeHeader(); - } - } - - public String getContentType() { - return this.contentType; - } - - public ServletInputStream getInputStream() { - if (this.content != null) { - return new DelegatingServletInputStream(new ByteArrayInputStream(this.content)); - } - else { - return null; - } - } - - /** - * Set a single value for the specified HTTP parameter. - * <p>If there are already one or more values registered for the given - * parameter name, they will be replaced. - */ - public void setParameter(String name, String value) { - setParameter(name, new String[] {value}); - } - - /** - * Set an array of values for the specified HTTP parameter. - * <p>If there are already one or more values registered for the given - * parameter name, they will be replaced. - */ - public void setParameter(String name, String[] values) { - Assert.notNull(name, "Parameter name must not be null"); - this.parameters.put(name, values); - } - - /** - * Sets all provided parameters <emphasis>replacing</emphasis> any - * existing values for the provided parameter names. To add without - * replacing existing values, use {@link #addParameters(java.util.Map)}. - */ - public void setParameters(Map params) { - Assert.notNull(params, "Parameter map must not be null"); - for (Object key : params.keySet()) { - Assert.isInstanceOf(String.class, key, - "Parameter map key must be of type [" + String.class.getName() + "]"); - Object value = params.get(key); - if (value instanceof String) { - this.setParameter((String) key, (String) value); - } - else if (value instanceof String[]) { - this.setParameter((String) key, (String[]) value); - } - else { - throw new IllegalArgumentException( - "Parameter map value must be single value " + " or array of type [" + String.class.getName() + - "]"); - } - } - } - - /** - * Add a single value for the specified HTTP parameter. - * <p>If there are already one or more values registered for the given - * parameter name, the given value will be added to the end of the list. - */ - public void addParameter(String name, String value) { - addParameter(name, new String[] {value}); - } - - /** - * Add an array of values for the specified HTTP parameter. - * <p>If there are already one or more values registered for the given - * parameter name, the given values will be added to the end of the list. - */ - public void addParameter(String name, String[] values) { - Assert.notNull(name, "Parameter name must not be null"); - String[] oldArr = this.parameters.get(name); - if (oldArr != null) { - String[] newArr = new String[oldArr.length + values.length]; - System.arraycopy(oldArr, 0, newArr, 0, oldArr.length); - System.arraycopy(values, 0, newArr, oldArr.length, values.length); - this.parameters.put(name, newArr); - } - else { - this.parameters.put(name, values); - } - } - - /** - * Adds all provided parameters <emphasis>without</emphasis> replacing - * any existing values. To replace existing values, use - * {@link #setParameters(java.util.Map)}. - */ - public void addParameters(Map params) { - Assert.notNull(params, "Parameter map must not be null"); - for (Object key : params.keySet()) { - Assert.isInstanceOf(String.class, key, - "Parameter map key must be of type [" + String.class.getName() + "]"); - Object value = params.get(key); - if (value instanceof String) { - this.addParameter((String) key, (String) value); - } - else if (value instanceof String[]) { - this.addParameter((String) key, (String[]) value); - } - else { - throw new IllegalArgumentException("Parameter map value must be single value " + - " or array of type [" + String.class.getName() + "]"); - } - } - } - - /** - * Remove already registered values for the specified HTTP parameter, if any. - */ - public void removeParameter(String name) { - Assert.notNull(name, "Parameter name must not be null"); - this.parameters.remove(name); - } - - /** - * Removes all existing parameters. - */ - public void removeAllParameters() { - this.parameters.clear(); - } - - public String getParameter(String name) { - Assert.notNull(name, "Parameter name must not be null"); - String[] arr = this.parameters.get(name); - return (arr != null && arr.length > 0 ? arr[0] : null); - } - - public Enumeration<String> getParameterNames() { - return Collections.enumeration(this.parameters.keySet()); - } - - public String[] getParameterValues(String name) { - Assert.notNull(name, "Parameter name must not be null"); - return this.parameters.get(name); - } - - public Map<String, String[]> getParameterMap() { - return Collections.unmodifiableMap(this.parameters); - } - - public void setProtocol(String protocol) { - this.protocol = protocol; - } - - public String getProtocol() { - return this.protocol; - } - - public void setScheme(String scheme) { - this.scheme = scheme; - } - - public String getScheme() { - return this.scheme; - } - - public void setServerName(String serverName) { - this.serverName = serverName; - } - - public String getServerName() { - return this.serverName; - } - - public void setServerPort(int serverPort) { - this.serverPort = serverPort; - } - - public int getServerPort() { - return this.serverPort; - } - - public BufferedReader getReader() throws UnsupportedEncodingException { - if (this.content != null) { - InputStream sourceStream = new ByteArrayInputStream(this.content); - Reader sourceReader = (this.characterEncoding != null) ? - new InputStreamReader(sourceStream, this.characterEncoding) : new InputStreamReader(sourceStream); - return new BufferedReader(sourceReader); - } - else { - return null; - } - } - - public void setRemoteAddr(String remoteAddr) { - this.remoteAddr = remoteAddr; - } - - public String getRemoteAddr() { - return this.remoteAddr; - } - - public void setRemoteHost(String remoteHost) { - this.remoteHost = remoteHost; - } - - public String getRemoteHost() { - return this.remoteHost; - } - - public void setAttribute(String name, Object value) { - checkActive(); - Assert.notNull(name, "Attribute name must not be null"); - if (value != null) { - this.attributes.put(name, value); - } - else { - this.attributes.remove(name); - } - } - - public void removeAttribute(String name) { - checkActive(); - Assert.notNull(name, "Attribute name must not be null"); - this.attributes.remove(name); - } - - /** - * Clear all of this request's attributes. - */ - public void clearAttributes() { - this.attributes.clear(); - } - - /** - * Add a new preferred locale, before any existing locales. - */ - public void addPreferredLocale(Locale locale) { - Assert.notNull(locale, "Locale must not be null"); - this.locales.add(0, locale); - } - - public Locale getLocale() { - return this.locales.get(0); - } - - public Enumeration<Locale> getLocales() { - return Collections.enumeration(this.locales); - } - - public void setSecure(boolean secure) { - this.secure = secure; - } - - public boolean isSecure() { - return this.secure; - } - - public RequestDispatcher getRequestDispatcher(String path) { - return new MockRequestDispatcher(path); - } - - public String getRealPath(String path) { - return this.servletContext.getRealPath(path); - } - - public void setRemotePort(int remotePort) { - this.remotePort = remotePort; - } - - public int getRemotePort() { - return this.remotePort; - } - - public void setLocalName(String localName) { - this.localName = localName; - } - - public String getLocalName() { - return this.localName; - } - - public void setLocalAddr(String localAddr) { - this.localAddr = localAddr; - } - - public String getLocalAddr() { - return this.localAddr; - } - - public void setLocalPort(int localPort) { - this.localPort = localPort; - } - - public int getLocalPort() { - return this.localPort; - } - - - //--------------------------------------------------------------------- - // HttpServletRequest interface - //--------------------------------------------------------------------- - - public void setAuthType(String authType) { - this.authType = authType; - } - - public String getAuthType() { - return this.authType; - } - - public void setCookies(Cookie... cookies) { - this.cookies = cookies; - } - - public Cookie[] getCookies() { - return this.cookies; - } - - /** - * Add a header entry for the given name. - * <p>If there was no entry for that header name before, - * the value will be used as-is. In case of an existing entry, - * a String array will be created, adding the given value (more - * specifically, its toString representation) as further element. - * <p>Multiple values can only be stored as list of Strings, - * following the Servlet spec (see <code>getHeaders</code> accessor). - * As alternative to repeated <code>addHeader</code> calls for - * individual elements, you can use a single call with an entire - * array or Collection of values as parameter. - * @see #getHeaderNames - * @see #getHeader - * @see #getHeaders - * @see #getDateHeader - * @see #getIntHeader - */ - public void addHeader(String name, Object value) { - if (CONTENT_TYPE_HEADER.equalsIgnoreCase(name)) { - setContentType((String) value); - return; - } - doAddHeaderValue(name, value, false); - } - - @SuppressWarnings("rawtypes") - private void doAddHeaderValue(String name, Object value, boolean replace) { - HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name); - Assert.notNull(value, "Header value must not be null"); - if (header == null || replace) { - header = new HeaderValueHolder(); - this.headers.put(name, header); - } - if (value instanceof Collection) { - header.addValues((Collection) value); - } - else if (value.getClass().isArray()) { - header.addValueArray(value); - } - else { - header.addValue(value); - } - } - - public long getDateHeader(String name) { - HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name); - Object value = (header != null ? header.getValue() : null); - if (value instanceof Date) { - return ((Date) value).getTime(); - } - else if (value instanceof Number) { - return ((Number) value).longValue(); - } - else if (value != null) { - throw new IllegalArgumentException( - "Value for header '" + name + "' is neither a Date nor a Number: " + value); - } - else { - return -1L; - } - } - - public String getHeader(String name) { - HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name); - return (header != null ? header.getValue().toString() : null); - } - - public Enumeration<String> getHeaders(String name) { - HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name); - return Collections.enumeration(header != null ? header.getStringValues() : new LinkedList<String>()); - } - - public Enumeration<String> getHeaderNames() { - return Collections.enumeration(this.headers.keySet()); - } - - public int getIntHeader(String name) { - HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name); - Object value = (header != null ? header.getValue() : null); - if (value instanceof Number) { - return ((Number) value).intValue(); - } - else if (value instanceof String) { - return Integer.parseInt((String) value); - } - else if (value != null) { - throw new NumberFormatException("Value for header '" + name + "' is not a Number: " + value); - } - else { - return -1; - } - } - - public void setMethod(String method) { - this.method = method; - } - - public String getMethod() { - return this.method; - } - - public void setPathInfo(String pathInfo) { - this.pathInfo = pathInfo; - } - - public String getPathInfo() { - return this.pathInfo; - } - - public String getPathTranslated() { - return (this.pathInfo != null ? getRealPath(this.pathInfo) : null); - } - - public void setContextPath(String contextPath) { - this.contextPath = contextPath; - } - - public String getContextPath() { - return this.contextPath; - } - - public void setQueryString(String queryString) { - this.queryString = queryString; - } - - public String getQueryString() { - return this.queryString; - } - - public void setRemoteUser(String remoteUser) { - this.remoteUser = remoteUser; - } - - public String getRemoteUser() { - return this.remoteUser; - } - - public void addUserRole(String role) { - this.userRoles.add(role); - } - - public boolean isUserInRole(String role) { - return this.userRoles.contains(role); - } - - public void setUserPrincipal(Principal userPrincipal) { - this.userPrincipal = userPrincipal; - } - - public Principal getUserPrincipal() { - return this.userPrincipal; - } - - public void setRequestedSessionId(String requestedSessionId) { - this.requestedSessionId = requestedSessionId; - } - - public String getRequestedSessionId() { - return this.requestedSessionId; - } - - public void setRequestURI(String requestURI) { - this.requestURI = requestURI; - } - - public String getRequestURI() { - return this.requestURI; - } - - public StringBuffer getRequestURL() { - StringBuffer url = new StringBuffer(this.scheme); - url.append("://").append(this.serverName).append(':').append(this.serverPort); - url.append(getRequestURI()); - return url; - } - - public void setServletPath(String servletPath) { - this.servletPath = servletPath; - } - - public String getServletPath() { - return this.servletPath; - } - - public void setSession(HttpSession session) { - this.session = session; - if (session instanceof MockHttpSession) { - MockHttpSession mockSession = ((MockHttpSession) session); - mockSession.access(); - } - } - - public HttpSession getSession(boolean create) { - checkActive(); - // Reset session if invalidated. - if (this.session instanceof MockHttpSession && ((MockHttpSession) this.session).isInvalid()) { - this.session = null; - } - // Create new session if necessary. - if (this.session == null && create) { - this.session = new MockHttpSession(this.servletContext); - } - return this.session; - } - - public HttpSession getSession() { - return getSession(true); - } - - public void setRequestedSessionIdValid(boolean requestedSessionIdValid) { - this.requestedSessionIdValid = requestedSessionIdValid; - } - - public boolean isRequestedSessionIdValid() { - return this.requestedSessionIdValid; - } - - public void setRequestedSessionIdFromCookie(boolean requestedSessionIdFromCookie) { - this.requestedSessionIdFromCookie = requestedSessionIdFromCookie; - } - - public boolean isRequestedSessionIdFromCookie() { - return this.requestedSessionIdFromCookie; - } - - public void setRequestedSessionIdFromURL(boolean requestedSessionIdFromURL) { - this.requestedSessionIdFromURL = requestedSessionIdFromURL; - } - - public boolean isRequestedSessionIdFromURL() { - return this.requestedSessionIdFromURL; - } - - public boolean isRequestedSessionIdFromUrl() { - return isRequestedSessionIdFromURL(); - } - - - //--------------------------------------------------------------------- - // Methods introduced in Servlet 3.0 - //--------------------------------------------------------------------- - - public AsyncContext getAsyncContext() { - throw new UnsupportedOperationException(); - } - - public DispatcherType getDispatcherType() { - throw new UnsupportedOperationException(); - } - - public boolean isAsyncSupported() { - throw new UnsupportedOperationException(); - } - - public AsyncContext startAsync() { - throw new UnsupportedOperationException(); - } - - public AsyncContext startAsync(ServletRequest arg0, ServletResponse arg1) { - throw new UnsupportedOperationException(); - } - - public boolean isAsyncStarted() { - throw new UnsupportedOperationException(); - } - - public boolean authenticate(HttpServletResponse arg0) throws IOException, ServletException { - throw new UnsupportedOperationException(); - } - - public void addPart(Part part) { - parts.put(part.getName(), part); - } - - public Part getPart(String key) throws IOException, IllegalStateException, ServletException { - return parts.get(key); - } - - public Collection<Part> getParts() throws IOException, IllegalStateException, ServletException { - return parts.values(); - } - - public void login(String arg0, String arg1) throws ServletException { - throw new UnsupportedOperationException(); - } - - public void logout() throws ServletException { - throw new UnsupportedOperationException(); - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.mock.web; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.UnsupportedEncodingException; +import java.security.Principal; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +import javax.servlet.AsyncContext; +import javax.servlet.DispatcherType; +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletInputStream; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import javax.servlet.http.Part; + +import org.springframework.util.Assert; +import org.springframework.util.LinkedCaseInsensitiveMap; + +/** + * Mock implementation of the {@link javax.servlet.http.HttpServletRequest} + * interface. Supports the Servlet 2.5 API level; throws + * {@link UnsupportedOperationException} for all methods introduced in Servlet 3.0. + * + * <p>Used for testing the web framework; also useful for testing + * application controllers. + * + * @author Juergen Hoeller + * @author Rod Johnson + * @author Rick Evans + * @author Mark Fisher + * @author Chris Beams + * @since 1.0.2 + */ +public class MockHttpServletRequest implements HttpServletRequest { + + /** + * The default protocol: 'http'. + */ + public static final String DEFAULT_PROTOCOL = "http"; + + /** + * The default server address: '127.0.0.1'. + */ + public static final String DEFAULT_SERVER_ADDR = "127.0.0.1"; + + /** + * The default server name: 'localhost'. + */ + public static final String DEFAULT_SERVER_NAME = "localhost"; + + /** + * The default server port: '80'. + */ + public static final int DEFAULT_SERVER_PORT = 80; + + /** + * The default remote address: '127.0.0.1'. + */ + public static final String DEFAULT_REMOTE_ADDR = "127.0.0.1"; + + /** + * The default remote host: 'localhost'. + */ + public static final String DEFAULT_REMOTE_HOST = "localhost"; + + private static final String CONTENT_TYPE_HEADER = "Content-Type"; + + private static final String CHARSET_PREFIX = "charset="; + + + private boolean active = true; + + + //--------------------------------------------------------------------- + // ServletRequest properties + //--------------------------------------------------------------------- + + private final Map<String, Object> attributes = new LinkedHashMap<String, Object>(); + + private String characterEncoding; + + private byte[] content; + + private String contentType; + + private final Map<String, String[]> parameters = new LinkedHashMap<String, String[]>(16); + + private String protocol = DEFAULT_PROTOCOL; + + private String scheme = DEFAULT_PROTOCOL; + + private String serverName = DEFAULT_SERVER_NAME; + + private int serverPort = DEFAULT_SERVER_PORT; + + private String remoteAddr = DEFAULT_REMOTE_ADDR; + + private String remoteHost = DEFAULT_REMOTE_HOST; + + /** List of locales in descending order */ + private final List<Locale> locales = new LinkedList<Locale>(); + + private boolean secure = false; + + private final ServletContext servletContext; + + private int remotePort = DEFAULT_SERVER_PORT; + + private String localName = DEFAULT_SERVER_NAME; + + private String localAddr = DEFAULT_SERVER_ADDR; + + private int localPort = DEFAULT_SERVER_PORT; + + private Map<String, Part> parts = new HashMap<String, Part>(); + + //--------------------------------------------------------------------- + // HttpServletRequest properties + //--------------------------------------------------------------------- + + private String authType; + + private Cookie[] cookies; + + private final Map<String, HeaderValueHolder> headers = new LinkedCaseInsensitiveMap<HeaderValueHolder>(); + + private String method; + + private String pathInfo; + + private String contextPath = ""; + + private String queryString; + + private String remoteUser; + + private final Set<String> userRoles = new HashSet<String>(); + + private Principal userPrincipal; + + private String requestedSessionId; + + private String requestURI; + + private String servletPath = ""; + + private HttpSession session; + + private boolean requestedSessionIdValid = true; + + private boolean requestedSessionIdFromCookie = true; + + private boolean requestedSessionIdFromURL = false; + + + //--------------------------------------------------------------------- + // Constructors + //--------------------------------------------------------------------- + + /** + * Create a new MockHttpServletRequest with a default + * {@link MockServletContext}. + * @see MockServletContext + */ + public MockHttpServletRequest() { + this(null, "", ""); + } + + /** + * Create a new MockHttpServletRequest with a default + * {@link MockServletContext}. + * @param method the request method (may be <code>null</code>) + * @param requestURI the request URI (may be <code>null</code>) + * @see #setMethod + * @see #setRequestURI + * @see MockServletContext + */ + public MockHttpServletRequest(String method, String requestURI) { + this(null, method, requestURI); + } + + /** + * Create a new MockHttpServletRequest. + * @param servletContext the ServletContext that the request runs in + * (may be <code>null</code> to use a default MockServletContext) + * @see MockServletContext + */ + public MockHttpServletRequest(ServletContext servletContext) { + this(servletContext, "", ""); + } + + /** + * Create a new MockHttpServletRequest. + * @param servletContext the ServletContext that the request runs in + * (may be <code>null</code> to use a default MockServletContext) + * @param method the request method (may be <code>null</code>) + * @param requestURI the request URI (may be <code>null</code>) + * @see #setMethod + * @see #setRequestURI + * @see MockServletContext + */ + public MockHttpServletRequest(ServletContext servletContext, String method, String requestURI) { + this.servletContext = (servletContext != null ? servletContext : new MockServletContext()); + this.method = method; + this.requestURI = requestURI; + this.locales.add(Locale.ENGLISH); + } + + + //--------------------------------------------------------------------- + // Lifecycle methods + //--------------------------------------------------------------------- + + /** + * Return the ServletContext that this request is associated with. + * (Not available in the standard HttpServletRequest interface for some reason.) + */ + public ServletContext getServletContext() { + return this.servletContext; + } + + /** + * Return whether this request is still active (that is, not completed yet). + */ + public boolean isActive() { + return this.active; + } + + /** + * Mark this request as completed, keeping its state. + */ + public void close() { + this.active = false; + } + + /** + * Invalidate this request, clearing its state. + */ + public void invalidate() { + close(); + clearAttributes(); + } + + /** + * Check whether this request is still active (that is, not completed yet), + * throwing an IllegalStateException if not active anymore. + */ + protected void checkActive() throws IllegalStateException { + if (!this.active) { + throw new IllegalStateException("Request is not active anymore"); + } + } + + + //--------------------------------------------------------------------- + // ServletRequest interface + //--------------------------------------------------------------------- + + public Object getAttribute(String name) { + checkActive(); + return this.attributes.get(name); + } + + public Enumeration<String> getAttributeNames() { + checkActive(); + return Collections.enumeration(this.attributes.keySet()); + } + + public String getCharacterEncoding() { + return this.characterEncoding; + } + + public void setCharacterEncoding(String characterEncoding) { + this.characterEncoding = characterEncoding; + updateContentTypeHeader(); + } + + private void updateContentTypeHeader() { + if (this.contentType != null) { + StringBuilder sb = new StringBuilder(this.contentType); + if (this.contentType.toLowerCase().indexOf(CHARSET_PREFIX) == -1 && this.characterEncoding != null) { + sb.append(";").append(CHARSET_PREFIX).append(this.characterEncoding); + } + doAddHeaderValue(CONTENT_TYPE_HEADER, sb.toString(), true); + } + } + + public void setContent(byte[] content) { + this.content = content; + } + + public int getContentLength() { + return (this.content != null ? this.content.length : -1); + } + + public void setContentType(String contentType) { + this.contentType = contentType; + if (contentType != null) { + int charsetIndex = contentType.toLowerCase().indexOf(CHARSET_PREFIX); + if (charsetIndex != -1) { + String encoding = contentType.substring(charsetIndex + CHARSET_PREFIX.length()); + this.characterEncoding = encoding; + } + updateContentTypeHeader(); + } + } + + public String getContentType() { + return this.contentType; + } + + public ServletInputStream getInputStream() { + if (this.content != null) { + return new DelegatingServletInputStream(new ByteArrayInputStream(this.content)); + } + else { + return null; + } + } + + /** + * Set a single value for the specified HTTP parameter. + * <p>If there are already one or more values registered for the given + * parameter name, they will be replaced. + */ + public void setParameter(String name, String value) { + setParameter(name, new String[] {value}); + } + + /** + * Set an array of values for the specified HTTP parameter. + * <p>If there are already one or more values registered for the given + * parameter name, they will be replaced. + */ + public void setParameter(String name, String[] values) { + Assert.notNull(name, "Parameter name must not be null"); + this.parameters.put(name, values); + } + + /** + * Sets all provided parameters <emphasis>replacing</emphasis> any + * existing values for the provided parameter names. To add without + * replacing existing values, use {@link #addParameters(java.util.Map)}. + */ + public void setParameters(Map params) { + Assert.notNull(params, "Parameter map must not be null"); + for (Object key : params.keySet()) { + Assert.isInstanceOf(String.class, key, + "Parameter map key must be of type [" + String.class.getName() + "]"); + Object value = params.get(key); + if (value instanceof String) { + this.setParameter((String) key, (String) value); + } + else if (value instanceof String[]) { + this.setParameter((String) key, (String[]) value); + } + else { + throw new IllegalArgumentException( + "Parameter map value must be single value " + " or array of type [" + String.class.getName() + + "]"); + } + } + } + + /** + * Add a single value for the specified HTTP parameter. + * <p>If there are already one or more values registered for the given + * parameter name, the given value will be added to the end of the list. + */ + public void addParameter(String name, String value) { + addParameter(name, new String[] {value}); + } + + /** + * Add an array of values for the specified HTTP parameter. + * <p>If there are already one or more values registered for the given + * parameter name, the given values will be added to the end of the list. + */ + public void addParameter(String name, String[] values) { + Assert.notNull(name, "Parameter name must not be null"); + String[] oldArr = this.parameters.get(name); + if (oldArr != null) { + String[] newArr = new String[oldArr.length + values.length]; + System.arraycopy(oldArr, 0, newArr, 0, oldArr.length); + System.arraycopy(values, 0, newArr, oldArr.length, values.length); + this.parameters.put(name, newArr); + } + else { + this.parameters.put(name, values); + } + } + + /** + * Adds all provided parameters <emphasis>without</emphasis> replacing + * any existing values. To replace existing values, use + * {@link #setParameters(java.util.Map)}. + */ + public void addParameters(Map params) { + Assert.notNull(params, "Parameter map must not be null"); + for (Object key : params.keySet()) { + Assert.isInstanceOf(String.class, key, + "Parameter map key must be of type [" + String.class.getName() + "]"); + Object value = params.get(key); + if (value instanceof String) { + this.addParameter((String) key, (String) value); + } + else if (value instanceof String[]) { + this.addParameter((String) key, (String[]) value); + } + else { + throw new IllegalArgumentException("Parameter map value must be single value " + + " or array of type [" + String.class.getName() + "]"); + } + } + } + + /** + * Remove already registered values for the specified HTTP parameter, if any. + */ + public void removeParameter(String name) { + Assert.notNull(name, "Parameter name must not be null"); + this.parameters.remove(name); + } + + /** + * Removes all existing parameters. + */ + public void removeAllParameters() { + this.parameters.clear(); + } + + public String getParameter(String name) { + Assert.notNull(name, "Parameter name must not be null"); + String[] arr = this.parameters.get(name); + return (arr != null && arr.length > 0 ? arr[0] : null); + } + + public Enumeration<String> getParameterNames() { + return Collections.enumeration(this.parameters.keySet()); + } + + public String[] getParameterValues(String name) { + Assert.notNull(name, "Parameter name must not be null"); + return this.parameters.get(name); + } + + public Map<String, String[]> getParameterMap() { + return Collections.unmodifiableMap(this.parameters); + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + public String getProtocol() { + return this.protocol; + } + + public void setScheme(String scheme) { + this.scheme = scheme; + } + + public String getScheme() { + return this.scheme; + } + + public void setServerName(String serverName) { + this.serverName = serverName; + } + + public String getServerName() { + return this.serverName; + } + + public void setServerPort(int serverPort) { + this.serverPort = serverPort; + } + + public int getServerPort() { + return this.serverPort; + } + + public BufferedReader getReader() throws UnsupportedEncodingException { + if (this.content != null) { + InputStream sourceStream = new ByteArrayInputStream(this.content); + Reader sourceReader = (this.characterEncoding != null) ? + new InputStreamReader(sourceStream, this.characterEncoding) : new InputStreamReader(sourceStream); + return new BufferedReader(sourceReader); + } + else { + return null; + } + } + + public void setRemoteAddr(String remoteAddr) { + this.remoteAddr = remoteAddr; + } + + public String getRemoteAddr() { + return this.remoteAddr; + } + + public void setRemoteHost(String remoteHost) { + this.remoteHost = remoteHost; + } + + public String getRemoteHost() { + return this.remoteHost; + } + + public void setAttribute(String name, Object value) { + checkActive(); + Assert.notNull(name, "Attribute name must not be null"); + if (value != null) { + this.attributes.put(name, value); + } + else { + this.attributes.remove(name); + } + } + + public void removeAttribute(String name) { + checkActive(); + Assert.notNull(name, "Attribute name must not be null"); + this.attributes.remove(name); + } + + /** + * Clear all of this request's attributes. + */ + public void clearAttributes() { + this.attributes.clear(); + } + + /** + * Add a new preferred locale, before any existing locales. + */ + public void addPreferredLocale(Locale locale) { + Assert.notNull(locale, "Locale must not be null"); + this.locales.add(0, locale); + } + + public Locale getLocale() { + return this.locales.get(0); + } + + public Enumeration<Locale> getLocales() { + return Collections.enumeration(this.locales); + } + + public void setSecure(boolean secure) { + this.secure = secure; + } + + public boolean isSecure() { + return this.secure; + } + + public RequestDispatcher getRequestDispatcher(String path) { + return new MockRequestDispatcher(path); + } + + public String getRealPath(String path) { + return this.servletContext.getRealPath(path); + } + + public void setRemotePort(int remotePort) { + this.remotePort = remotePort; + } + + public int getRemotePort() { + return this.remotePort; + } + + public void setLocalName(String localName) { + this.localName = localName; + } + + public String getLocalName() { + return this.localName; + } + + public void setLocalAddr(String localAddr) { + this.localAddr = localAddr; + } + + public String getLocalAddr() { + return this.localAddr; + } + + public void setLocalPort(int localPort) { + this.localPort = localPort; + } + + public int getLocalPort() { + return this.localPort; + } + + + //--------------------------------------------------------------------- + // HttpServletRequest interface + //--------------------------------------------------------------------- + + public void setAuthType(String authType) { + this.authType = authType; + } + + public String getAuthType() { + return this.authType; + } + + public void setCookies(Cookie... cookies) { + this.cookies = cookies; + } + + public Cookie[] getCookies() { + return this.cookies; + } + + /** + * Add a header entry for the given name. + * <p>If there was no entry for that header name before, + * the value will be used as-is. In case of an existing entry, + * a String array will be created, adding the given value (more + * specifically, its toString representation) as further element. + * <p>Multiple values can only be stored as list of Strings, + * following the Servlet spec (see <code>getHeaders</code> accessor). + * As alternative to repeated <code>addHeader</code> calls for + * individual elements, you can use a single call with an entire + * array or Collection of values as parameter. + * @see #getHeaderNames + * @see #getHeader + * @see #getHeaders + * @see #getDateHeader + * @see #getIntHeader + */ + public void addHeader(String name, Object value) { + if (CONTENT_TYPE_HEADER.equalsIgnoreCase(name)) { + setContentType((String) value); + return; + } + doAddHeaderValue(name, value, false); + } + + @SuppressWarnings("rawtypes") + private void doAddHeaderValue(String name, Object value, boolean replace) { + HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name); + Assert.notNull(value, "Header value must not be null"); + if (header == null || replace) { + header = new HeaderValueHolder(); + this.headers.put(name, header); + } + if (value instanceof Collection) { + header.addValues((Collection) value); + } + else if (value.getClass().isArray()) { + header.addValueArray(value); + } + else { + header.addValue(value); + } + } + + public long getDateHeader(String name) { + HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name); + Object value = (header != null ? header.getValue() : null); + if (value instanceof Date) { + return ((Date) value).getTime(); + } + else if (value instanceof Number) { + return ((Number) value).longValue(); + } + else if (value != null) { + throw new IllegalArgumentException( + "Value for header '" + name + "' is neither a Date nor a Number: " + value); + } + else { + return -1L; + } + } + + public String getHeader(String name) { + HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name); + return (header != null ? header.getValue().toString() : null); + } + + public Enumeration<String> getHeaders(String name) { + HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name); + return Collections.enumeration(header != null ? header.getStringValues() : new LinkedList<String>()); + } + + public Enumeration<String> getHeaderNames() { + return Collections.enumeration(this.headers.keySet()); + } + + public int getIntHeader(String name) { + HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name); + Object value = (header != null ? header.getValue() : null); + if (value instanceof Number) { + return ((Number) value).intValue(); + } + else if (value instanceof String) { + return Integer.parseInt((String) value); + } + else if (value != null) { + throw new NumberFormatException("Value for header '" + name + "' is not a Number: " + value); + } + else { + return -1; + } + } + + public void setMethod(String method) { + this.method = method; + } + + public String getMethod() { + return this.method; + } + + public void setPathInfo(String pathInfo) { + this.pathInfo = pathInfo; + } + + public String getPathInfo() { + return this.pathInfo; + } + + public String getPathTranslated() { + return (this.pathInfo != null ? getRealPath(this.pathInfo) : null); + } + + public void setContextPath(String contextPath) { + this.contextPath = contextPath; + } + + public String getContextPath() { + return this.contextPath; + } + + public void setQueryString(String queryString) { + this.queryString = queryString; + } + + public String getQueryString() { + return this.queryString; + } + + public void setRemoteUser(String remoteUser) { + this.remoteUser = remoteUser; + } + + public String getRemoteUser() { + return this.remoteUser; + } + + public void addUserRole(String role) { + this.userRoles.add(role); + } + + public boolean isUserInRole(String role) { + return this.userRoles.contains(role); + } + + public void setUserPrincipal(Principal userPrincipal) { + this.userPrincipal = userPrincipal; + } + + public Principal getUserPrincipal() { + return this.userPrincipal; + } + + public void setRequestedSessionId(String requestedSessionId) { + this.requestedSessionId = requestedSessionId; + } + + public String getRequestedSessionId() { + return this.requestedSessionId; + } + + public void setRequestURI(String requestURI) { + this.requestURI = requestURI; + } + + public String getRequestURI() { + return this.requestURI; + } + + public StringBuffer getRequestURL() { + StringBuffer url = new StringBuffer(this.scheme); + url.append("://").append(this.serverName).append(':').append(this.serverPort); + url.append(getRequestURI()); + return url; + } + + public void setServletPath(String servletPath) { + this.servletPath = servletPath; + } + + public String getServletPath() { + return this.servletPath; + } + + public void setSession(HttpSession session) { + this.session = session; + if (session instanceof MockHttpSession) { + MockHttpSession mockSession = ((MockHttpSession) session); + mockSession.access(); + } + } + + public HttpSession getSession(boolean create) { + checkActive(); + // Reset session if invalidated. + if (this.session instanceof MockHttpSession && ((MockHttpSession) this.session).isInvalid()) { + this.session = null; + } + // Create new session if necessary. + if (this.session == null && create) { + this.session = new MockHttpSession(this.servletContext); + } + return this.session; + } + + public HttpSession getSession() { + return getSession(true); + } + + public void setRequestedSessionIdValid(boolean requestedSessionIdValid) { + this.requestedSessionIdValid = requestedSessionIdValid; + } + + public boolean isRequestedSessionIdValid() { + return this.requestedSessionIdValid; + } + + public void setRequestedSessionIdFromCookie(boolean requestedSessionIdFromCookie) { + this.requestedSessionIdFromCookie = requestedSessionIdFromCookie; + } + + public boolean isRequestedSessionIdFromCookie() { + return this.requestedSessionIdFromCookie; + } + + public void setRequestedSessionIdFromURL(boolean requestedSessionIdFromURL) { + this.requestedSessionIdFromURL = requestedSessionIdFromURL; + } + + public boolean isRequestedSessionIdFromURL() { + return this.requestedSessionIdFromURL; + } + + public boolean isRequestedSessionIdFromUrl() { + return isRequestedSessionIdFromURL(); + } + + + //--------------------------------------------------------------------- + // Methods introduced in Servlet 3.0 + //--------------------------------------------------------------------- + + public AsyncContext getAsyncContext() { + throw new UnsupportedOperationException(); + } + + public DispatcherType getDispatcherType() { + throw new UnsupportedOperationException(); + } + + public boolean isAsyncSupported() { + throw new UnsupportedOperationException(); + } + + public AsyncContext startAsync() { + throw new UnsupportedOperationException(); + } + + public AsyncContext startAsync(ServletRequest arg0, ServletResponse arg1) { + throw new UnsupportedOperationException(); + } + + public boolean isAsyncStarted() { + throw new UnsupportedOperationException(); + } + + public boolean authenticate(HttpServletResponse arg0) throws IOException, ServletException { + throw new UnsupportedOperationException(); + } + + public void addPart(Part part) { + parts.put(part.getName(), part); + } + + public Part getPart(String key) throws IOException, IllegalStateException, ServletException { + return parts.get(key); + } + + public Collection<Part> getParts() throws IOException, IllegalStateException, ServletException { + return parts.values(); + } + + public void login(String arg0, String arg1) throws ServletException { + throw new UnsupportedOperationException(); + } + + public void logout() throws ServletException { + throw new UnsupportedOperationException(); + } + +} diff --git a/org.springframework.web/src/test/java/org/springframework/mock/web/MockHttpSession.java b/org.springframework.web/src/test/java/org/springframework/mock/web/MockHttpSession.java index 3803e93712d..757414dbbcc 100644 --- a/org.springframework.web/src/test/java/org/springframework/mock/web/MockHttpSession.java +++ b/org.springframework.web/src/test/java/org/springframework/mock/web/MockHttpSession.java @@ -1,246 +1,246 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.mock.web; - -import java.io.Serializable; -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.Map; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpSession; -import javax.servlet.http.HttpSessionBindingEvent; -import javax.servlet.http.HttpSessionBindingListener; -import javax.servlet.http.HttpSessionContext; - -import org.springframework.util.Assert; - -/** - * Mock implementation of the {@link javax.servlet.http.HttpSession} interface. - * Supports the Servlet 2.4 API level. - * - * <p>Used for testing the web framework; also useful for testing - * application controllers. - * - * @author Juergen Hoeller - * @author Rod Johnson - * @author Mark Fisher - * @since 1.0.2 - */ -public class MockHttpSession implements HttpSession { - - public static final String SESSION_COOKIE_NAME = "JSESSION"; - - private static int nextId = 1; - - - private final String id; - - private final long creationTime = System.currentTimeMillis(); - - private int maxInactiveInterval; - - private long lastAccessedTime = System.currentTimeMillis(); - - private final ServletContext servletContext; - - private final Map<String, Object> attributes = new LinkedHashMap<String, Object>(); - - private boolean invalid = false; - - private boolean isNew = true; - - - /** - * Create a new MockHttpSession with a default {@link MockServletContext}. - * @see MockServletContext - */ - public MockHttpSession() { - this(null); - } - - /** - * Create a new MockHttpSession. - * @param servletContext the ServletContext that the session runs in - */ - public MockHttpSession(ServletContext servletContext) { - this(servletContext, null); - } - - /** - * Create a new MockHttpSession. - * @param servletContext the ServletContext that the session runs in - * @param id a unique identifier for this session - */ - public MockHttpSession(ServletContext servletContext, String id) { - this.servletContext = (servletContext != null ? servletContext : new MockServletContext()); - this.id = (id != null ? id : Integer.toString(nextId++)); - } - - - public long getCreationTime() { - return this.creationTime; - } - - public String getId() { - return this.id; - } - - public void access() { - this.lastAccessedTime = System.currentTimeMillis(); - this.isNew = false; - } - - public long getLastAccessedTime() { - return this.lastAccessedTime; - } - - public ServletContext getServletContext() { - return this.servletContext; - } - - public void setMaxInactiveInterval(int interval) { - this.maxInactiveInterval = interval; - } - - public int getMaxInactiveInterval() { - return this.maxInactiveInterval; - } - - public HttpSessionContext getSessionContext() { - throw new UnsupportedOperationException("getSessionContext"); - } - - public Object getAttribute(String name) { - Assert.notNull(name, "Attribute name must not be null"); - return this.attributes.get(name); - } - - public Object getValue(String name) { - return getAttribute(name); - } - - public Enumeration<String> getAttributeNames() { - return Collections.enumeration(this.attributes.keySet()); - } - - public String[] getValueNames() { - return this.attributes.keySet().toArray(new String[this.attributes.size()]); - } - - public void setAttribute(String name, Object value) { - Assert.notNull(name, "Attribute name must not be null"); - if (value != null) { - this.attributes.put(name, value); - if (value instanceof HttpSessionBindingListener) { - ((HttpSessionBindingListener) value).valueBound(new HttpSessionBindingEvent(this, name, value)); - } - } - else { - removeAttribute(name); - } - } - - public void putValue(String name, Object value) { - setAttribute(name, value); - } - - public void removeAttribute(String name) { - Assert.notNull(name, "Attribute name must not be null"); - Object value = this.attributes.remove(name); - if (value instanceof HttpSessionBindingListener) { - ((HttpSessionBindingListener) value).valueUnbound(new HttpSessionBindingEvent(this, name, value)); - } - } - - public void removeValue(String name) { - removeAttribute(name); - } - - /** - * Clear all of this session's attributes. - */ - public void clearAttributes() { - for (Iterator<Map.Entry<String, Object>> it = this.attributes.entrySet().iterator(); it.hasNext();) { - Map.Entry<String, Object> entry = it.next(); - String name = entry.getKey(); - Object value = entry.getValue(); - it.remove(); - if (value instanceof HttpSessionBindingListener) { - ((HttpSessionBindingListener) value).valueUnbound(new HttpSessionBindingEvent(this, name, value)); - } - } - } - - public void invalidate() { - this.invalid = true; - clearAttributes(); - } - - public boolean isInvalid() { - return this.invalid; - } - - public void setNew(boolean value) { - this.isNew = value; - } - - public boolean isNew() { - return this.isNew; - } - - - /** - * Serialize the attributes of this session into an object that can - * be turned into a byte array with standard Java serialization. - * @return a representation of this session's serialized state - */ - public Serializable serializeState() { - HashMap<String, Serializable> state = new HashMap<String, Serializable>(); - for (Iterator<Map.Entry<String, Object>> it = this.attributes.entrySet().iterator(); it.hasNext();) { - Map.Entry<String, Object> entry = it.next(); - String name = entry.getKey(); - Object value = entry.getValue(); - it.remove(); - if (value instanceof Serializable) { - state.put(name, (Serializable) value); - } - else { - // Not serializable... Servlet containers usually automatically - // unbind the attribute in this case. - if (value instanceof HttpSessionBindingListener) { - ((HttpSessionBindingListener) value).valueUnbound(new HttpSessionBindingEvent(this, name, value)); - } - } - } - return state; - } - - /** - * Deserialize the attributes of this session from a state object - * created by {@link #serializeState()}. - * @param state a representation of this session's serialized state - */ - @SuppressWarnings("unchecked") - public void deserializeState(Serializable state) { - Assert.isTrue(state instanceof Map, "Serialized state needs to be of type [java.util.Map]"); - this.attributes.putAll((Map<String, Object>) state); - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.mock.web; + +import java.io.Serializable; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpSession; +import javax.servlet.http.HttpSessionBindingEvent; +import javax.servlet.http.HttpSessionBindingListener; +import javax.servlet.http.HttpSessionContext; + +import org.springframework.util.Assert; + +/** + * Mock implementation of the {@link javax.servlet.http.HttpSession} interface. + * Supports the Servlet 2.4 API level. + * + * <p>Used for testing the web framework; also useful for testing + * application controllers. + * + * @author Juergen Hoeller + * @author Rod Johnson + * @author Mark Fisher + * @since 1.0.2 + */ +public class MockHttpSession implements HttpSession { + + public static final String SESSION_COOKIE_NAME = "JSESSION"; + + private static int nextId = 1; + + + private final String id; + + private final long creationTime = System.currentTimeMillis(); + + private int maxInactiveInterval; + + private long lastAccessedTime = System.currentTimeMillis(); + + private final ServletContext servletContext; + + private final Map<String, Object> attributes = new LinkedHashMap<String, Object>(); + + private boolean invalid = false; + + private boolean isNew = true; + + + /** + * Create a new MockHttpSession with a default {@link MockServletContext}. + * @see MockServletContext + */ + public MockHttpSession() { + this(null); + } + + /** + * Create a new MockHttpSession. + * @param servletContext the ServletContext that the session runs in + */ + public MockHttpSession(ServletContext servletContext) { + this(servletContext, null); + } + + /** + * Create a new MockHttpSession. + * @param servletContext the ServletContext that the session runs in + * @param id a unique identifier for this session + */ + public MockHttpSession(ServletContext servletContext, String id) { + this.servletContext = (servletContext != null ? servletContext : new MockServletContext()); + this.id = (id != null ? id : Integer.toString(nextId++)); + } + + + public long getCreationTime() { + return this.creationTime; + } + + public String getId() { + return this.id; + } + + public void access() { + this.lastAccessedTime = System.currentTimeMillis(); + this.isNew = false; + } + + public long getLastAccessedTime() { + return this.lastAccessedTime; + } + + public ServletContext getServletContext() { + return this.servletContext; + } + + public void setMaxInactiveInterval(int interval) { + this.maxInactiveInterval = interval; + } + + public int getMaxInactiveInterval() { + return this.maxInactiveInterval; + } + + public HttpSessionContext getSessionContext() { + throw new UnsupportedOperationException("getSessionContext"); + } + + public Object getAttribute(String name) { + Assert.notNull(name, "Attribute name must not be null"); + return this.attributes.get(name); + } + + public Object getValue(String name) { + return getAttribute(name); + } + + public Enumeration<String> getAttributeNames() { + return Collections.enumeration(this.attributes.keySet()); + } + + public String[] getValueNames() { + return this.attributes.keySet().toArray(new String[this.attributes.size()]); + } + + public void setAttribute(String name, Object value) { + Assert.notNull(name, "Attribute name must not be null"); + if (value != null) { + this.attributes.put(name, value); + if (value instanceof HttpSessionBindingListener) { + ((HttpSessionBindingListener) value).valueBound(new HttpSessionBindingEvent(this, name, value)); + } + } + else { + removeAttribute(name); + } + } + + public void putValue(String name, Object value) { + setAttribute(name, value); + } + + public void removeAttribute(String name) { + Assert.notNull(name, "Attribute name must not be null"); + Object value = this.attributes.remove(name); + if (value instanceof HttpSessionBindingListener) { + ((HttpSessionBindingListener) value).valueUnbound(new HttpSessionBindingEvent(this, name, value)); + } + } + + public void removeValue(String name) { + removeAttribute(name); + } + + /** + * Clear all of this session's attributes. + */ + public void clearAttributes() { + for (Iterator<Map.Entry<String, Object>> it = this.attributes.entrySet().iterator(); it.hasNext();) { + Map.Entry<String, Object> entry = it.next(); + String name = entry.getKey(); + Object value = entry.getValue(); + it.remove(); + if (value instanceof HttpSessionBindingListener) { + ((HttpSessionBindingListener) value).valueUnbound(new HttpSessionBindingEvent(this, name, value)); + } + } + } + + public void invalidate() { + this.invalid = true; + clearAttributes(); + } + + public boolean isInvalid() { + return this.invalid; + } + + public void setNew(boolean value) { + this.isNew = value; + } + + public boolean isNew() { + return this.isNew; + } + + + /** + * Serialize the attributes of this session into an object that can + * be turned into a byte array with standard Java serialization. + * @return a representation of this session's serialized state + */ + public Serializable serializeState() { + HashMap<String, Serializable> state = new HashMap<String, Serializable>(); + for (Iterator<Map.Entry<String, Object>> it = this.attributes.entrySet().iterator(); it.hasNext();) { + Map.Entry<String, Object> entry = it.next(); + String name = entry.getKey(); + Object value = entry.getValue(); + it.remove(); + if (value instanceof Serializable) { + state.put(name, (Serializable) value); + } + else { + // Not serializable... Servlet containers usually automatically + // unbind the attribute in this case. + if (value instanceof HttpSessionBindingListener) { + ((HttpSessionBindingListener) value).valueUnbound(new HttpSessionBindingEvent(this, name, value)); + } + } + } + return state; + } + + /** + * Deserialize the attributes of this session from a state object + * created by {@link #serializeState()}. + * @param state a representation of this session's serialized state + */ + @SuppressWarnings("unchecked") + public void deserializeState(Serializable state) { + Assert.isTrue(state instanceof Map, "Serialized state needs to be of type [java.util.Map]"); + this.attributes.putAll((Map<String, Object>) state); + } + +} diff --git a/org.springframework.web/src/test/java/org/springframework/mock/web/MockRequestDispatcher.java b/org.springframework.web/src/test/java/org/springframework/mock/web/MockRequestDispatcher.java index 396f0e7fd54..a87bea43c91 100644 --- a/org.springframework.web/src/test/java/org/springframework/mock/web/MockRequestDispatcher.java +++ b/org.springframework.web/src/test/java/org/springframework/mock/web/MockRequestDispatcher.java @@ -1,91 +1,91 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.mock.web; - -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletResponseWrapper; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.util.Assert; - -/** - * Mock implementation of the {@link javax.servlet.RequestDispatcher} interface. - * - * <p>Used for testing the web framework; typically not necessary for - * testing application controllers. - * - * @author Rod Johnson - * @author Juergen Hoeller - * @since 1.0.2 - */ -public class MockRequestDispatcher implements RequestDispatcher { - - private final Log logger = LogFactory.getLog(getClass()); - - private final String url; - - - /** - * Create a new MockRequestDispatcher for the given URL. - * @param url the URL to dispatch to. - */ - public MockRequestDispatcher(String url) { - Assert.notNull(url, "URL must not be null"); - this.url = url; - } - - - public void forward(ServletRequest request, ServletResponse response) { - Assert.notNull(request, "Request must not be null"); - Assert.notNull(response, "Response must not be null"); - if (response.isCommitted()) { - throw new IllegalStateException("Cannot perform forward - response is already committed"); - } - getMockHttpServletResponse(response).setForwardedUrl(this.url); - if (logger.isDebugEnabled()) { - logger.debug("MockRequestDispatcher: forwarding to URL [" + this.url + "]"); - } - } - - public void include(ServletRequest request, ServletResponse response) { - Assert.notNull(request, "Request must not be null"); - Assert.notNull(response, "Response must not be null"); - getMockHttpServletResponse(response).addIncludedUrl(this.url); - if (logger.isDebugEnabled()) { - logger.debug("MockRequestDispatcher: including URL [" + this.url + "]"); - } - } - - /** - * Obtain the underlying MockHttpServletResponse, - * unwrapping {@link HttpServletResponseWrapper} decorators if necessary. - */ - protected MockHttpServletResponse getMockHttpServletResponse(ServletResponse response) { - if (response instanceof MockHttpServletResponse) { - return (MockHttpServletResponse) response; - } - if (response instanceof HttpServletResponseWrapper) { - return getMockHttpServletResponse(((HttpServletResponseWrapper) response).getResponse()); - } - throw new IllegalArgumentException("MockRequestDispatcher requires MockHttpServletResponse"); - } - -} +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.mock.web; + +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletResponseWrapper; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.springframework.util.Assert; + +/** + * Mock implementation of the {@link javax.servlet.RequestDispatcher} interface. + * + * <p>Used for testing the web framework; typically not necessary for + * testing application controllers. + * + * @author Rod Johnson + * @author Juergen Hoeller + * @since 1.0.2 + */ +public class MockRequestDispatcher implements RequestDispatcher { + + private final Log logger = LogFactory.getLog(getClass()); + + private final String url; + + + /** + * Create a new MockRequestDispatcher for the given URL. + * @param url the URL to dispatch to. + */ + public MockRequestDispatcher(String url) { + Assert.notNull(url, "URL must not be null"); + this.url = url; + } + + + public void forward(ServletRequest request, ServletResponse response) { + Assert.notNull(request, "Request must not be null"); + Assert.notNull(response, "Response must not be null"); + if (response.isCommitted()) { + throw new IllegalStateException("Cannot perform forward - response is already committed"); + } + getMockHttpServletResponse(response).setForwardedUrl(this.url); + if (logger.isDebugEnabled()) { + logger.debug("MockRequestDispatcher: forwarding to URL [" + this.url + "]"); + } + } + + public void include(ServletRequest request, ServletResponse response) { + Assert.notNull(request, "Request must not be null"); + Assert.notNull(response, "Response must not be null"); + getMockHttpServletResponse(response).addIncludedUrl(this.url); + if (logger.isDebugEnabled()) { + logger.debug("MockRequestDispatcher: including URL [" + this.url + "]"); + } + } + + /** + * Obtain the underlying MockHttpServletResponse, + * unwrapping {@link HttpServletResponseWrapper} decorators if necessary. + */ + protected MockHttpServletResponse getMockHttpServletResponse(ServletResponse response) { + if (response instanceof MockHttpServletResponse) { + return (MockHttpServletResponse) response; + } + if (response instanceof HttpServletResponseWrapper) { + return getMockHttpServletResponse(((HttpServletResponseWrapper) response).getResponse()); + } + throw new IllegalArgumentException("MockRequestDispatcher requires MockHttpServletResponse"); + } + +} diff --git a/org.springframework.web/src/test/java/org/springframework/mock/web/MockServletContext.java b/org.springframework.web/src/test/java/org/springframework/mock/web/MockServletContext.java index 828af03d2e9..cd9d391735a 100644 --- a/org.springframework.web/src/test/java/org/springframework/mock/web/MockServletContext.java +++ b/org.springframework.web/src/test/java/org/springframework/mock/web/MockServletContext.java @@ -1,507 +1,507 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.mock.web; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Collections; -import java.util.Enumeration; -import java.util.EventListener; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Set; -import javax.activation.FileTypeMap; -import javax.servlet.Filter; -import javax.servlet.FilterRegistration; -import javax.servlet.FilterRegistration.Dynamic; -import javax.servlet.RequestDispatcher; -import javax.servlet.Servlet; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRegistration; -import javax.servlet.SessionCookieConfig; -import javax.servlet.SessionTrackingMode; -import javax.servlet.descriptor.JspConfigDescriptor; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.core.io.DefaultResourceLoader; -import org.springframework.core.io.Resource; -import org.springframework.core.io.ResourceLoader; -import org.springframework.util.Assert; -import org.springframework.util.ObjectUtils; -import org.springframework.web.util.WebUtils; - -/** - * Mock implementation of the {@link javax.servlet.ServletContext} interface. - * - * <p>Used for testing the Spring web framework; only rarely necessary for testing - * application controllers. As long as application components don't explicitly - * access the ServletContext, ClassPathXmlApplicationContext or - * FileSystemXmlApplicationContext can be used to load the context files for testing, - * even for DispatcherServlet context definitions. - * - * <p>For setting up a full WebApplicationContext in a test environment, you can - * use XmlWebApplicationContext (or GenericWebApplicationContext), passing in an - * appropriate MockServletContext instance. You might want to configure your - * MockServletContext with a FileSystemResourceLoader in that case, to make your - * resource paths interpreted as relative file system locations. - * - * <p>A common setup is to point your JVM working directory to the root of your - * web application directory, in combination with filesystem-based resource loading. - * This allows to load the context files as used in the web application, with - * relative paths getting interpreted correctly. Such a setup will work with both - * FileSystemXmlApplicationContext (which will load straight from the file system) - * and XmlWebApplicationContext with an underlying MockServletContext (as long as - * the MockServletContext has been configured with a FileSystemResourceLoader). - * - * <p>Supports Servlet 3.0 API level, but throws {@link UnsupportedOperationException} - * for most methods introduced in Servlet 3.0. - * - * @author Rod Johnson - * @author Juergen Hoeller - * @author Chris Beams - * @since 1.0.2 - * @see #MockServletContext(org.springframework.core.io.ResourceLoader) - * @see org.springframework.web.context.support.XmlWebApplicationContext - * @see org.springframework.web.context.support.GenericWebApplicationContext - * @see org.springframework.context.support.ClassPathXmlApplicationContext - * @see org.springframework.context.support.FileSystemXmlApplicationContext - */ -public class MockServletContext implements ServletContext { - - private static final String TEMP_DIR_SYSTEM_PROPERTY = "java.io.tmpdir"; - - - private final Log logger = LogFactory.getLog(getClass()); - - private final ResourceLoader resourceLoader; - - private final String resourceBasePath; - - private String contextPath = ""; - - private int majorVersion = 2; - - private int minorVersion = 5; - - private int effectiveMajorVersion = 2; - - private int effectiveMinorVersion = 5; - - private final Map<String, ServletContext> contexts = new HashMap<String, ServletContext>(); - - private final Map<String, String> initParameters = new LinkedHashMap<String, String>(); - - private final Map<String, Object> attributes = new LinkedHashMap<String, Object>(); - - private String servletContextName = "MockServletContext"; - - - /** - * Create a new MockServletContext, using no base path and a - * DefaultResourceLoader (i.e. the classpath root as WAR root). - * @see org.springframework.core.io.DefaultResourceLoader - */ - public MockServletContext() { - this("", null); - } - - /** - * Create a new MockServletContext, using a DefaultResourceLoader. - * @param resourceBasePath the WAR root directory (should not end with a slash) - * @see org.springframework.core.io.DefaultResourceLoader - */ - public MockServletContext(String resourceBasePath) { - this(resourceBasePath, null); - } - - /** - * Create a new MockServletContext, using the specified ResourceLoader - * and no base path. - * @param resourceLoader the ResourceLoader to use (or null for the default) - */ - public MockServletContext(ResourceLoader resourceLoader) { - this("", resourceLoader); - } - - /** - * Create a new MockServletContext. - * @param resourceBasePath the WAR root directory (should not end with a slash) - * @param resourceLoader the ResourceLoader to use (or null for the default) - */ - public MockServletContext(String resourceBasePath, ResourceLoader resourceLoader) { - this.resourceLoader = (resourceLoader != null ? resourceLoader : new DefaultResourceLoader()); - this.resourceBasePath = (resourceBasePath != null ? resourceBasePath : ""); - - // Use JVM temp dir as ServletContext temp dir. - String tempDir = System.getProperty(TEMP_DIR_SYSTEM_PROPERTY); - if (tempDir != null) { - this.attributes.put(WebUtils.TEMP_DIR_CONTEXT_ATTRIBUTE, new File(tempDir)); - } - } - - - /** - * Build a full resource location for the given path, - * prepending the resource base path of this MockServletContext. - * @param path the path as specified - * @return the full resource path - */ - protected String getResourceLocation(String path) { - if (!path.startsWith("/")) { - path = "/" + path; - } - return this.resourceBasePath + path; - } - - - public void setContextPath(String contextPath) { - this.contextPath = (contextPath != null ? contextPath : ""); - } - - /* This is a Servlet API 2.5 method. */ - public String getContextPath() { - return this.contextPath; - } - - public void registerContext(String contextPath, ServletContext context) { - this.contexts.put(contextPath, context); - } - - public ServletContext getContext(String contextPath) { - if (this.contextPath.equals(contextPath)) { - return this; - } - return this.contexts.get(contextPath); - } - - public void setMajorVersion(int majorVersion) { - this.majorVersion = majorVersion; - } - - public int getMajorVersion() { - return this.majorVersion; - } - - public void setMinorVersion(int minorVersion) { - this.minorVersion = minorVersion; - } - - public int getMinorVersion() { - return this.minorVersion; - } - - public void setEffectiveMajorVersion(int effectiveMajorVersion) { - this.effectiveMajorVersion = effectiveMajorVersion; - } - - public int getEffectiveMajorVersion() { - return this.effectiveMajorVersion; - } - - public void setEffectiveMinorVersion(int effectiveMinorVersion) { - this.effectiveMinorVersion = effectiveMinorVersion; - } - - public int getEffectiveMinorVersion() { - return this.effectiveMinorVersion; - } - - public String getMimeType(String filePath) { - return MimeTypeResolver.getMimeType(filePath); - } - - public Set<String> getResourcePaths(String path) { - String actualPath = (path.endsWith("/") ? path : path + "/"); - Resource resource = this.resourceLoader.getResource(getResourceLocation(actualPath)); - try { - File file = resource.getFile(); - String[] fileList = file.list(); - if (ObjectUtils.isEmpty(fileList)) { - return null; - } - Set<String> resourcePaths = new LinkedHashSet<String>(fileList.length); - for (String fileEntry : fileList) { - String resultPath = actualPath + fileEntry; - if (resource.createRelative(fileEntry).getFile().isDirectory()) { - resultPath += "/"; - } - resourcePaths.add(resultPath); - } - return resourcePaths; - } - catch (IOException ex) { - logger.warn("Couldn't get resource paths for " + resource, ex); - return null; - } - } - - public URL getResource(String path) throws MalformedURLException { - Resource resource = this.resourceLoader.getResource(getResourceLocation(path)); - if (!resource.exists()) { - return null; - } - try { - return resource.getURL(); - } - catch (MalformedURLException ex) { - throw ex; - } - catch (IOException ex) { - logger.warn("Couldn't get URL for " + resource, ex); - return null; - } - } - - public InputStream getResourceAsStream(String path) { - Resource resource = this.resourceLoader.getResource(getResourceLocation(path)); - if (!resource.exists()) { - return null; - } - try { - return resource.getInputStream(); - } - catch (IOException ex) { - logger.warn("Couldn't open InputStream for " + resource, ex); - return null; - } - } - - public RequestDispatcher getRequestDispatcher(String path) { - if (!path.startsWith("/")) { - throw new IllegalArgumentException("RequestDispatcher path at ServletContext level must start with '/'"); - } - return new MockRequestDispatcher(path); - } - - public RequestDispatcher getNamedDispatcher(String path) { - return null; - } - - public Servlet getServlet(String name) { - return null; - } - - public Enumeration<Servlet> getServlets() { - return Collections.enumeration(new HashSet<Servlet>()); - } - - public Enumeration<String> getServletNames() { - return Collections.enumeration(new HashSet<String>()); - } - - public void log(String message) { - logger.info(message); - } - - public void log(Exception ex, String message) { - logger.info(message, ex); - } - - public void log(String message, Throwable ex) { - logger.info(message, ex); - } - - public String getRealPath(String path) { - Resource resource = this.resourceLoader.getResource(getResourceLocation(path)); - try { - return resource.getFile().getAbsolutePath(); - } - catch (IOException ex) { - logger.warn("Couldn't determine real path of resource " + resource, ex); - return null; - } - } - - public String getServerInfo() { - return "MockServletContext"; - } - - public String getInitParameter(String name) { - Assert.notNull(name, "Parameter name must not be null"); - return this.initParameters.get(name); - } - - public void addInitParameter(String name, String value) { - Assert.notNull(name, "Parameter name must not be null"); - this.initParameters.put(name, value); - } - - public Enumeration<String> getInitParameterNames() { - return Collections.enumeration(this.initParameters.keySet()); - } - - public Object getAttribute(String name) { - Assert.notNull(name, "Attribute name must not be null"); - return this.attributes.get(name); - } - - public Enumeration<String> getAttributeNames() { - return Collections.enumeration(this.attributes.keySet()); - } - - public void setAttribute(String name, Object value) { - Assert.notNull(name, "Attribute name must not be null"); - if (value != null) { - this.attributes.put(name, value); - } - else { - this.attributes.remove(name); - } - } - - public void removeAttribute(String name) { - Assert.notNull(name, "Attribute name must not be null"); - this.attributes.remove(name); - } - - public void setServletContextName(String servletContextName) { - this.servletContextName = servletContextName; - } - - public String getServletContextName() { - return this.servletContextName; - } - - - /** - * Inner factory class used to just introduce a Java Activation Framework - * dependency when actually asked to resolve a MIME type. - */ - private static class MimeTypeResolver { - - public static String getMimeType(String filePath) { - return FileTypeMap.getDefaultFileTypeMap().getContentType(filePath); - } - } - - - //--------------------------------------------------------------------- - // Methods introduced in Servlet 3.0 - //--------------------------------------------------------------------- - - public Dynamic addFilter(String arg0, String arg1) { - throw new UnsupportedOperationException(); - } - - public Dynamic addFilter(String arg0, Filter arg1) { - throw new UnsupportedOperationException(); - } - - public Dynamic addFilter(String arg0, Class<? extends Filter> arg1) { - throw new UnsupportedOperationException(); - } - - public void addListener(Class<? extends EventListener> arg0) { - throw new UnsupportedOperationException(); - } - - public void addListener(String arg0) { - throw new UnsupportedOperationException(); - } - - public <T extends EventListener> void addListener(T arg0) { - throw new UnsupportedOperationException(); - } - - public javax.servlet.ServletRegistration.Dynamic addServlet(String arg0, String arg1) { - throw new UnsupportedOperationException(); - } - - public javax.servlet.ServletRegistration.Dynamic addServlet(String arg0, - Servlet arg1) { - throw new UnsupportedOperationException(); - } - - public javax.servlet.ServletRegistration.Dynamic addServlet(String arg0, - Class<? extends Servlet> arg1) { - throw new UnsupportedOperationException(); - } - - public <T extends Filter> T createFilter(Class<T> arg0) - throws ServletException { - throw new UnsupportedOperationException(); - } - - public <T extends EventListener> T createListener(Class<T> arg0) - throws ServletException { - throw new UnsupportedOperationException(); - } - - public <T extends Servlet> T createServlet(Class<T> arg0) - throws ServletException { - throw new UnsupportedOperationException(); - } - - public void declareRoles(String... arg0) { - throw new UnsupportedOperationException(); - } - - public ClassLoader getClassLoader() { - throw new UnsupportedOperationException(); - } - - public Set<SessionTrackingMode> getDefaultSessionTrackingModes() { - throw new UnsupportedOperationException(); - } - - public Set<SessionTrackingMode> getEffectiveSessionTrackingModes() { - throw new UnsupportedOperationException(); - } - - public FilterRegistration getFilterRegistration(String arg0) { - throw new UnsupportedOperationException(); - } - - public Map<String, ? extends FilterRegistration> getFilterRegistrations() { - throw new UnsupportedOperationException(); - } - - public JspConfigDescriptor getJspConfigDescriptor() { - throw new UnsupportedOperationException(); - } - - public ServletRegistration getServletRegistration(String arg0) { - throw new UnsupportedOperationException(); - } - - public Map<String, ? extends ServletRegistration> getServletRegistrations() { - throw new UnsupportedOperationException(); - } - - public SessionCookieConfig getSessionCookieConfig() { - throw new UnsupportedOperationException(); - } - - public boolean setInitParameter(String arg0, String arg1) { - throw new UnsupportedOperationException(); - } - - public void setSessionTrackingModes(Set<SessionTrackingMode> arg0) - throws IllegalStateException, IllegalArgumentException { - throw new UnsupportedOperationException(); - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.mock.web; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Collections; +import java.util.Enumeration; +import java.util.EventListener; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; +import javax.activation.FileTypeMap; +import javax.servlet.Filter; +import javax.servlet.FilterRegistration; +import javax.servlet.FilterRegistration.Dynamic; +import javax.servlet.RequestDispatcher; +import javax.servlet.Servlet; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletRegistration; +import javax.servlet.SessionCookieConfig; +import javax.servlet.SessionTrackingMode; +import javax.servlet.descriptor.JspConfigDescriptor; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.springframework.core.io.DefaultResourceLoader; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.springframework.util.Assert; +import org.springframework.util.ObjectUtils; +import org.springframework.web.util.WebUtils; + +/** + * Mock implementation of the {@link javax.servlet.ServletContext} interface. + * + * <p>Used for testing the Spring web framework; only rarely necessary for testing + * application controllers. As long as application components don't explicitly + * access the ServletContext, ClassPathXmlApplicationContext or + * FileSystemXmlApplicationContext can be used to load the context files for testing, + * even for DispatcherServlet context definitions. + * + * <p>For setting up a full WebApplicationContext in a test environment, you can + * use XmlWebApplicationContext (or GenericWebApplicationContext), passing in an + * appropriate MockServletContext instance. You might want to configure your + * MockServletContext with a FileSystemResourceLoader in that case, to make your + * resource paths interpreted as relative file system locations. + * + * <p>A common setup is to point your JVM working directory to the root of your + * web application directory, in combination with filesystem-based resource loading. + * This allows to load the context files as used in the web application, with + * relative paths getting interpreted correctly. Such a setup will work with both + * FileSystemXmlApplicationContext (which will load straight from the file system) + * and XmlWebApplicationContext with an underlying MockServletContext (as long as + * the MockServletContext has been configured with a FileSystemResourceLoader). + * + * <p>Supports Servlet 3.0 API level, but throws {@link UnsupportedOperationException} + * for most methods introduced in Servlet 3.0. + * + * @author Rod Johnson + * @author Juergen Hoeller + * @author Chris Beams + * @since 1.0.2 + * @see #MockServletContext(org.springframework.core.io.ResourceLoader) + * @see org.springframework.web.context.support.XmlWebApplicationContext + * @see org.springframework.web.context.support.GenericWebApplicationContext + * @see org.springframework.context.support.ClassPathXmlApplicationContext + * @see org.springframework.context.support.FileSystemXmlApplicationContext + */ +public class MockServletContext implements ServletContext { + + private static final String TEMP_DIR_SYSTEM_PROPERTY = "java.io.tmpdir"; + + + private final Log logger = LogFactory.getLog(getClass()); + + private final ResourceLoader resourceLoader; + + private final String resourceBasePath; + + private String contextPath = ""; + + private int majorVersion = 2; + + private int minorVersion = 5; + + private int effectiveMajorVersion = 2; + + private int effectiveMinorVersion = 5; + + private final Map<String, ServletContext> contexts = new HashMap<String, ServletContext>(); + + private final Map<String, String> initParameters = new LinkedHashMap<String, String>(); + + private final Map<String, Object> attributes = new LinkedHashMap<String, Object>(); + + private String servletContextName = "MockServletContext"; + + + /** + * Create a new MockServletContext, using no base path and a + * DefaultResourceLoader (i.e. the classpath root as WAR root). + * @see org.springframework.core.io.DefaultResourceLoader + */ + public MockServletContext() { + this("", null); + } + + /** + * Create a new MockServletContext, using a DefaultResourceLoader. + * @param resourceBasePath the WAR root directory (should not end with a slash) + * @see org.springframework.core.io.DefaultResourceLoader + */ + public MockServletContext(String resourceBasePath) { + this(resourceBasePath, null); + } + + /** + * Create a new MockServletContext, using the specified ResourceLoader + * and no base path. + * @param resourceLoader the ResourceLoader to use (or null for the default) + */ + public MockServletContext(ResourceLoader resourceLoader) { + this("", resourceLoader); + } + + /** + * Create a new MockServletContext. + * @param resourceBasePath the WAR root directory (should not end with a slash) + * @param resourceLoader the ResourceLoader to use (or null for the default) + */ + public MockServletContext(String resourceBasePath, ResourceLoader resourceLoader) { + this.resourceLoader = (resourceLoader != null ? resourceLoader : new DefaultResourceLoader()); + this.resourceBasePath = (resourceBasePath != null ? resourceBasePath : ""); + + // Use JVM temp dir as ServletContext temp dir. + String tempDir = System.getProperty(TEMP_DIR_SYSTEM_PROPERTY); + if (tempDir != null) { + this.attributes.put(WebUtils.TEMP_DIR_CONTEXT_ATTRIBUTE, new File(tempDir)); + } + } + + + /** + * Build a full resource location for the given path, + * prepending the resource base path of this MockServletContext. + * @param path the path as specified + * @return the full resource path + */ + protected String getResourceLocation(String path) { + if (!path.startsWith("/")) { + path = "/" + path; + } + return this.resourceBasePath + path; + } + + + public void setContextPath(String contextPath) { + this.contextPath = (contextPath != null ? contextPath : ""); + } + + /* This is a Servlet API 2.5 method. */ + public String getContextPath() { + return this.contextPath; + } + + public void registerContext(String contextPath, ServletContext context) { + this.contexts.put(contextPath, context); + } + + public ServletContext getContext(String contextPath) { + if (this.contextPath.equals(contextPath)) { + return this; + } + return this.contexts.get(contextPath); + } + + public void setMajorVersion(int majorVersion) { + this.majorVersion = majorVersion; + } + + public int getMajorVersion() { + return this.majorVersion; + } + + public void setMinorVersion(int minorVersion) { + this.minorVersion = minorVersion; + } + + public int getMinorVersion() { + return this.minorVersion; + } + + public void setEffectiveMajorVersion(int effectiveMajorVersion) { + this.effectiveMajorVersion = effectiveMajorVersion; + } + + public int getEffectiveMajorVersion() { + return this.effectiveMajorVersion; + } + + public void setEffectiveMinorVersion(int effectiveMinorVersion) { + this.effectiveMinorVersion = effectiveMinorVersion; + } + + public int getEffectiveMinorVersion() { + return this.effectiveMinorVersion; + } + + public String getMimeType(String filePath) { + return MimeTypeResolver.getMimeType(filePath); + } + + public Set<String> getResourcePaths(String path) { + String actualPath = (path.endsWith("/") ? path : path + "/"); + Resource resource = this.resourceLoader.getResource(getResourceLocation(actualPath)); + try { + File file = resource.getFile(); + String[] fileList = file.list(); + if (ObjectUtils.isEmpty(fileList)) { + return null; + } + Set<String> resourcePaths = new LinkedHashSet<String>(fileList.length); + for (String fileEntry : fileList) { + String resultPath = actualPath + fileEntry; + if (resource.createRelative(fileEntry).getFile().isDirectory()) { + resultPath += "/"; + } + resourcePaths.add(resultPath); + } + return resourcePaths; + } + catch (IOException ex) { + logger.warn("Couldn't get resource paths for " + resource, ex); + return null; + } + } + + public URL getResource(String path) throws MalformedURLException { + Resource resource = this.resourceLoader.getResource(getResourceLocation(path)); + if (!resource.exists()) { + return null; + } + try { + return resource.getURL(); + } + catch (MalformedURLException ex) { + throw ex; + } + catch (IOException ex) { + logger.warn("Couldn't get URL for " + resource, ex); + return null; + } + } + + public InputStream getResourceAsStream(String path) { + Resource resource = this.resourceLoader.getResource(getResourceLocation(path)); + if (!resource.exists()) { + return null; + } + try { + return resource.getInputStream(); + } + catch (IOException ex) { + logger.warn("Couldn't open InputStream for " + resource, ex); + return null; + } + } + + public RequestDispatcher getRequestDispatcher(String path) { + if (!path.startsWith("/")) { + throw new IllegalArgumentException("RequestDispatcher path at ServletContext level must start with '/'"); + } + return new MockRequestDispatcher(path); + } + + public RequestDispatcher getNamedDispatcher(String path) { + return null; + } + + public Servlet getServlet(String name) { + return null; + } + + public Enumeration<Servlet> getServlets() { + return Collections.enumeration(new HashSet<Servlet>()); + } + + public Enumeration<String> getServletNames() { + return Collections.enumeration(new HashSet<String>()); + } + + public void log(String message) { + logger.info(message); + } + + public void log(Exception ex, String message) { + logger.info(message, ex); + } + + public void log(String message, Throwable ex) { + logger.info(message, ex); + } + + public String getRealPath(String path) { + Resource resource = this.resourceLoader.getResource(getResourceLocation(path)); + try { + return resource.getFile().getAbsolutePath(); + } + catch (IOException ex) { + logger.warn("Couldn't determine real path of resource " + resource, ex); + return null; + } + } + + public String getServerInfo() { + return "MockServletContext"; + } + + public String getInitParameter(String name) { + Assert.notNull(name, "Parameter name must not be null"); + return this.initParameters.get(name); + } + + public void addInitParameter(String name, String value) { + Assert.notNull(name, "Parameter name must not be null"); + this.initParameters.put(name, value); + } + + public Enumeration<String> getInitParameterNames() { + return Collections.enumeration(this.initParameters.keySet()); + } + + public Object getAttribute(String name) { + Assert.notNull(name, "Attribute name must not be null"); + return this.attributes.get(name); + } + + public Enumeration<String> getAttributeNames() { + return Collections.enumeration(this.attributes.keySet()); + } + + public void setAttribute(String name, Object value) { + Assert.notNull(name, "Attribute name must not be null"); + if (value != null) { + this.attributes.put(name, value); + } + else { + this.attributes.remove(name); + } + } + + public void removeAttribute(String name) { + Assert.notNull(name, "Attribute name must not be null"); + this.attributes.remove(name); + } + + public void setServletContextName(String servletContextName) { + this.servletContextName = servletContextName; + } + + public String getServletContextName() { + return this.servletContextName; + } + + + /** + * Inner factory class used to just introduce a Java Activation Framework + * dependency when actually asked to resolve a MIME type. + */ + private static class MimeTypeResolver { + + public static String getMimeType(String filePath) { + return FileTypeMap.getDefaultFileTypeMap().getContentType(filePath); + } + } + + + //--------------------------------------------------------------------- + // Methods introduced in Servlet 3.0 + //--------------------------------------------------------------------- + + public Dynamic addFilter(String arg0, String arg1) { + throw new UnsupportedOperationException(); + } + + public Dynamic addFilter(String arg0, Filter arg1) { + throw new UnsupportedOperationException(); + } + + public Dynamic addFilter(String arg0, Class<? extends Filter> arg1) { + throw new UnsupportedOperationException(); + } + + public void addListener(Class<? extends EventListener> arg0) { + throw new UnsupportedOperationException(); + } + + public void addListener(String arg0) { + throw new UnsupportedOperationException(); + } + + public <T extends EventListener> void addListener(T arg0) { + throw new UnsupportedOperationException(); + } + + public javax.servlet.ServletRegistration.Dynamic addServlet(String arg0, String arg1) { + throw new UnsupportedOperationException(); + } + + public javax.servlet.ServletRegistration.Dynamic addServlet(String arg0, + Servlet arg1) { + throw new UnsupportedOperationException(); + } + + public javax.servlet.ServletRegistration.Dynamic addServlet(String arg0, + Class<? extends Servlet> arg1) { + throw new UnsupportedOperationException(); + } + + public <T extends Filter> T createFilter(Class<T> arg0) + throws ServletException { + throw new UnsupportedOperationException(); + } + + public <T extends EventListener> T createListener(Class<T> arg0) + throws ServletException { + throw new UnsupportedOperationException(); + } + + public <T extends Servlet> T createServlet(Class<T> arg0) + throws ServletException { + throw new UnsupportedOperationException(); + } + + public void declareRoles(String... arg0) { + throw new UnsupportedOperationException(); + } + + public ClassLoader getClassLoader() { + throw new UnsupportedOperationException(); + } + + public Set<SessionTrackingMode> getDefaultSessionTrackingModes() { + throw new UnsupportedOperationException(); + } + + public Set<SessionTrackingMode> getEffectiveSessionTrackingModes() { + throw new UnsupportedOperationException(); + } + + public FilterRegistration getFilterRegistration(String arg0) { + throw new UnsupportedOperationException(); + } + + public Map<String, ? extends FilterRegistration> getFilterRegistrations() { + throw new UnsupportedOperationException(); + } + + public JspConfigDescriptor getJspConfigDescriptor() { + throw new UnsupportedOperationException(); + } + + public ServletRegistration getServletRegistration(String arg0) { + throw new UnsupportedOperationException(); + } + + public Map<String, ? extends ServletRegistration> getServletRegistrations() { + throw new UnsupportedOperationException(); + } + + public SessionCookieConfig getSessionCookieConfig() { + throw new UnsupportedOperationException(); + } + + public boolean setInitParameter(String arg0, String arg1) { + throw new UnsupportedOperationException(); + } + + public void setSessionTrackingModes(Set<SessionTrackingMode> arg0) + throws IllegalStateException, IllegalArgumentException { + throw new UnsupportedOperationException(); + } + +} diff --git a/org.springframework.web/src/test/java/org/springframework/web/context/request/WebApplicationContextScopeTests.java b/org.springframework.web/src/test/java/org/springframework/web/context/request/WebApplicationContextScopeTests.java index 26ef5cd60e6..7366c555b60 100644 --- a/org.springframework.web/src/test/java/org/springframework/web/context/request/WebApplicationContextScopeTests.java +++ b/org.springframework.web/src/test/java/org/springframework/web/context/request/WebApplicationContextScopeTests.java @@ -1,100 +1,100 @@ -/* - * Copyright 2002-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.context.request; - -import javax.servlet.ServletContextEvent; - -import static org.junit.Assert.*; -import org.junit.Test; - -import org.springframework.beans.DerivedTestBean; -import org.springframework.beans.factory.support.GenericBeanDefinition; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockServletContext; -import org.springframework.web.context.ContextCleanupListener; -import org.springframework.web.context.WebApplicationContext; -import org.springframework.web.context.support.GenericWebApplicationContext; - -/** - * @author Juergen Hoeller - */ -public class WebApplicationContextScopeTests { - - private static final String NAME = "scoped"; - - - private WebApplicationContext initApplicationContext(String scope) { - MockServletContext sc = new MockServletContext(); - GenericWebApplicationContext ac = new GenericWebApplicationContext(sc); - GenericBeanDefinition bd = new GenericBeanDefinition(); - bd.setBeanClass(DerivedTestBean.class); - bd.setScope(scope); - ac.registerBeanDefinition(NAME, bd); - ac.refresh(); - return ac; - } - - @Test - public void testRequestScope() { - WebApplicationContext ac = initApplicationContext(WebApplicationContext.SCOPE_REQUEST); - MockHttpServletRequest request = new MockHttpServletRequest(); - ServletRequestAttributes requestAttributes = new ServletRequestAttributes(request); - RequestContextHolder.setRequestAttributes(requestAttributes); - try { - assertNull(request.getAttribute(NAME)); - DerivedTestBean bean = ac.getBean(NAME, DerivedTestBean.class); - assertSame(bean, request.getAttribute(NAME)); - assertSame(bean, ac.getBean(NAME)); - requestAttributes.requestCompleted(); - assertTrue(bean.wasDestroyed()); - } - finally { - RequestContextHolder.setRequestAttributes(null); - } - } - - @Test - public void testSessionScope() { - WebApplicationContext ac = initApplicationContext(WebApplicationContext.SCOPE_SESSION); - MockHttpServletRequest request = new MockHttpServletRequest(); - ServletRequestAttributes requestAttributes = new ServletRequestAttributes(request); - RequestContextHolder.setRequestAttributes(requestAttributes); - try { - assertNull(request.getSession().getAttribute(NAME)); - DerivedTestBean bean = ac.getBean(NAME, DerivedTestBean.class); - assertSame(bean, request.getSession().getAttribute(NAME)); - assertSame(bean, ac.getBean(NAME)); - request.getSession().invalidate(); - assertTrue(bean.wasDestroyed()); - } - finally { - RequestContextHolder.setRequestAttributes(null); - } - } - - @Test - public void testApplicationScope() { - WebApplicationContext ac = initApplicationContext(WebApplicationContext.SCOPE_APPLICATION); - assertNull(ac.getServletContext().getAttribute(NAME)); - DerivedTestBean bean = ac.getBean(NAME, DerivedTestBean.class); - assertSame(bean, ac.getServletContext().getAttribute(NAME)); - assertSame(bean, ac.getBean(NAME)); - new ContextCleanupListener().contextDestroyed(new ServletContextEvent(ac.getServletContext())); - assertTrue(bean.wasDestroyed()); - } - -} +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.web.context.request; + +import javax.servlet.ServletContextEvent; + +import static org.junit.Assert.*; +import org.junit.Test; + +import org.springframework.beans.DerivedTestBean; +import org.springframework.beans.factory.support.GenericBeanDefinition; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockServletContext; +import org.springframework.web.context.ContextCleanupListener; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.context.support.GenericWebApplicationContext; + +/** + * @author Juergen Hoeller + */ +public class WebApplicationContextScopeTests { + + private static final String NAME = "scoped"; + + + private WebApplicationContext initApplicationContext(String scope) { + MockServletContext sc = new MockServletContext(); + GenericWebApplicationContext ac = new GenericWebApplicationContext(sc); + GenericBeanDefinition bd = new GenericBeanDefinition(); + bd.setBeanClass(DerivedTestBean.class); + bd.setScope(scope); + ac.registerBeanDefinition(NAME, bd); + ac.refresh(); + return ac; + } + + @Test + public void testRequestScope() { + WebApplicationContext ac = initApplicationContext(WebApplicationContext.SCOPE_REQUEST); + MockHttpServletRequest request = new MockHttpServletRequest(); + ServletRequestAttributes requestAttributes = new ServletRequestAttributes(request); + RequestContextHolder.setRequestAttributes(requestAttributes); + try { + assertNull(request.getAttribute(NAME)); + DerivedTestBean bean = ac.getBean(NAME, DerivedTestBean.class); + assertSame(bean, request.getAttribute(NAME)); + assertSame(bean, ac.getBean(NAME)); + requestAttributes.requestCompleted(); + assertTrue(bean.wasDestroyed()); + } + finally { + RequestContextHolder.setRequestAttributes(null); + } + } + + @Test + public void testSessionScope() { + WebApplicationContext ac = initApplicationContext(WebApplicationContext.SCOPE_SESSION); + MockHttpServletRequest request = new MockHttpServletRequest(); + ServletRequestAttributes requestAttributes = new ServletRequestAttributes(request); + RequestContextHolder.setRequestAttributes(requestAttributes); + try { + assertNull(request.getSession().getAttribute(NAME)); + DerivedTestBean bean = ac.getBean(NAME, DerivedTestBean.class); + assertSame(bean, request.getSession().getAttribute(NAME)); + assertSame(bean, ac.getBean(NAME)); + request.getSession().invalidate(); + assertTrue(bean.wasDestroyed()); + } + finally { + RequestContextHolder.setRequestAttributes(null); + } + } + + @Test + public void testApplicationScope() { + WebApplicationContext ac = initApplicationContext(WebApplicationContext.SCOPE_APPLICATION); + assertNull(ac.getServletContext().getAttribute(NAME)); + DerivedTestBean bean = ac.getBean(NAME, DerivedTestBean.class); + assertSame(bean, ac.getServletContext().getAttribute(NAME)); + assertSame(bean, ac.getBean(NAME)); + new ContextCleanupListener().contextDestroyed(new ServletContextEvent(ac.getServletContext())); + assertTrue(bean.wasDestroyed()); + } + +} diff --git a/org.springframework.web/src/test/java/org/springframework/web/context/support/SpringBeanAutowiringSupportTests.java b/org.springframework.web/src/test/java/org/springframework/web/context/support/SpringBeanAutowiringSupportTests.java index dfa22e3a5c0..72ac783005c 100644 --- a/org.springframework.web/src/test/java/org/springframework/web/context/support/SpringBeanAutowiringSupportTests.java +++ b/org.springframework.web/src/test/java/org/springframework/web/context/support/SpringBeanAutowiringSupportTests.java @@ -1,62 +1,62 @@ -/* - * Copyright 2002-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.context.support; - -import org.junit.Test; - -import org.springframework.beans.ITestBean; -import org.springframework.beans.MutablePropertyValues; -import org.springframework.beans.TestBean; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.mock.web.MockServletContext; -import org.springframework.web.context.WebApplicationContext; - -import static org.junit.Assert.*; - -/** - * @author Juergen Hoeller - */ -public class SpringBeanAutowiringSupportTests { - - @Test - public void testProcessInjectionBasedOnServletContext() { - MockServletContext sc = new MockServletContext(); - StaticWebApplicationContext wac = new StaticWebApplicationContext(); - MutablePropertyValues pvs = new MutablePropertyValues(); - pvs.add("name", "tb"); - wac.registerSingleton("testBean", TestBean.class, pvs); - wac.setServletContext(sc); - wac.refresh(); - sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac); - InjectionTarget target = new InjectionTarget(); - SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(target, sc); - assertTrue(target.testBean instanceof TestBean); - assertEquals("tb", target.name); - } - - - public static class InjectionTarget { - - @Autowired - public ITestBean testBean; - - @Value("#{testBean.name}") - public String name; - } - -} +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.web.context.support; + +import org.junit.Test; + +import org.springframework.beans.ITestBean; +import org.springframework.beans.MutablePropertyValues; +import org.springframework.beans.TestBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.mock.web.MockServletContext; +import org.springframework.web.context.WebApplicationContext; + +import static org.junit.Assert.*; + +/** + * @author Juergen Hoeller + */ +public class SpringBeanAutowiringSupportTests { + + @Test + public void testProcessInjectionBasedOnServletContext() { + MockServletContext sc = new MockServletContext(); + StaticWebApplicationContext wac = new StaticWebApplicationContext(); + MutablePropertyValues pvs = new MutablePropertyValues(); + pvs.add("name", "tb"); + wac.registerSingleton("testBean", TestBean.class, pvs); + wac.setServletContext(sc); + wac.refresh(); + sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac); + InjectionTarget target = new InjectionTarget(); + SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(target, sc); + assertTrue(target.testBean instanceof TestBean); + assertEquals("tb", target.name); + } + + + public static class InjectionTarget { + + @Autowired + public ITestBean testBean; + + @Value("#{testBean.name}") + public String name; + } + +} From 36d941fc996e1b78ee78235ce890061f5772475c Mon Sep 17 00:00:00 2001 From: Chris Beams <cbeams@vmware.com> Date: Tue, 20 Dec 2011 10:36:59 +0100 Subject: [PATCH 07/22] Add readme --- README.md | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000000..d6768727022 --- /dev/null +++ b/README.md @@ -0,0 +1,58 @@ +## Spring Framework +The Spring Framework provides a comprehensive programming and configuration model for modern +Java-based enterprise applications - on any kind of deployment platform. A key element of Spring is +infrastructural support at the application level: Spring focuses on the "plumbing" of enterprise +applications so that teams can focus on application-level business logic, without unnecessary ties +to specific deployment environments. + +The framework also serves as the foundation for +[Spring Integration](https://github.com/SpringSource/spring-integration), +[Spring Batch](https://github.com/SpringSource/spring-batch) and the rest of the Spring family of +projects. Browse the repositories under the +[SpringSource organization](https://github.com/SpringSource) on GitHub for a full list. + +[.NET](https://github.com/SpringSource/spring-net) and +[Python](https://github.com/SpringSource/spring-python) variants are available as well. + +## Downloading artifacts +Instructions on +[downloading Spring artifacts](https://github.com/SpringSource/spring-framework/wiki/Downloading-Spring-artifacts) +via Maven and other build systems are available via the project wiki. + +## Documentation +See the current [Javadoc](http://static.springsource.org/spring/docs/current/javadoc-api) +and [Reference docs](http://static.springsource.org/spring/docs/current/spring-framework-reference). + +## Getting support +Check out the [Spring forums](http://forum.springsource.org) and the +[Spring tag](http://stackoverflow.com/questions/tagged/spring) on StackOverflow. +[Commercial support](http://springsource.com/support/springsupport) is available too. + +## Issue Tracking +Spring's JIRA issue tracker can be found [here](http://jira.springsource.org/browse/SPR). Think +you've found a bug? Please consider submitting a reproduction project via the +[spring-framework-issues](https://github.com/springsource/spring-framework-issues) repository. The +[readme](https://github.com/springsource/spring-framework-issues#readme) provides simple +step-by-step instructions. + +## Building from source +Instructions on +[building Spring from source](https://github.com/SpringSource/spring-framework/wiki/Building-from-source) +are available via the project wiki. + +## Contributing +[Pull requests](http://help.github.com/send-pull-requests) are welcome; you'll be asked to sign our +contributor license agreement ([CLA](https://support.springsource.com/spring_committer_signup)). +Trivial changes like typo fixes are especially appreciated (just +[fork and edit!](https://github.com/blog/844-forking-with-the-edit-button)). For larger changes, +please create a JIRA issue first and discuss your ideas with the Spring team. + +## Staying in touch +Follow [@springframework](http://twitter.com/springframework) and its +[team members](http://twitter.com/springframework/team/members) on Twitter. In-depth articles can be +found at the SpringSource [team blog](http://blog.springsource.org), and releases are announced via +our [news feed](http://www.springsource.org/news-events). + +## License +The Spring Framework is released under version 2.0 of the +[Apache License](http://www.apache.org/licenses/LICENSE-2.0). From 02452a1af95e66df56088853495ccf8dc85be1ff Mon Sep 17 00:00:00 2001 From: Chris Beams <cbeams@vmware.com> Date: Tue, 20 Dec 2011 20:23:25 +0100 Subject: [PATCH 08/22] Minor copy edits to README --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d6768727022..5aa077745ea 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,8 @@ to specific deployment environments. The framework also serves as the foundation for [Spring Integration](https://github.com/SpringSource/spring-integration), -[Spring Batch](https://github.com/SpringSource/spring-batch) and the rest of the Spring family of -projects. Browse the repositories under the +[Spring Batch](https://github.com/SpringSource/spring-batch) and the rest of the Spring +[family of projects](http://springsource.org/projects). Browse the repositories under the [SpringSource organization](https://github.com/SpringSource) on GitHub for a full list. [.NET](https://github.com/SpringSource/spring-net) and @@ -45,7 +45,8 @@ are available via the project wiki. contributor license agreement ([CLA](https://support.springsource.com/spring_committer_signup)). Trivial changes like typo fixes are especially appreciated (just [fork and edit!](https://github.com/blog/844-forking-with-the-edit-button)). For larger changes, -please create a JIRA issue first and discuss your ideas with the Spring team. +please search through JIRA for similiar issues, creating a new one if necessary, and discuss your +ideas with the Spring team. ## Staying in touch Follow [@springframework](http://twitter.com/springframework) and its From e0231438cdfa75bcbd34bae28765e2afcb0c4121 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller <jhoeller@vmware.com> Date: Wed, 21 Dec 2011 12:41:37 +0100 Subject: [PATCH 09/22] fixed "packagesToScan" to avoid additional provider scan (SPR-8936) --- .../orm/jpa/persistenceunit/DefaultPersistenceUnitManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/jpa/persistenceunit/DefaultPersistenceUnitManager.java b/org.springframework.orm/src/main/java/org/springframework/orm/jpa/persistenceunit/DefaultPersistenceUnitManager.java index c4ad75f777e..2afd92abca2 100644 --- a/org.springframework.orm/src/main/java/org/springframework/orm/jpa/persistenceunit/DefaultPersistenceUnitManager.java +++ b/org.springframework.orm/src/main/java/org/springframework/orm/jpa/persistenceunit/DefaultPersistenceUnitManager.java @@ -390,7 +390,7 @@ public class DefaultPersistenceUnitManager private SpringPersistenceUnitInfo buildDefaultPersistenceUnitInfo() { SpringPersistenceUnitInfo scannedUnit = new SpringPersistenceUnitInfo(); scannedUnit.setPersistenceUnitName(this.defaultPersistenceUnitName); - scannedUnit.excludeUnlistedClasses(); + scannedUnit.setExcludeUnlistedClasses(true); if (this.packagesToScan != null) { for (String pkg : this.packagesToScan) { try { From cc2e558fe0cdcde3c422f8a869bac9dd507297e7 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller <jhoeller@vmware.com> Date: Wed, 21 Dec 2011 12:43:04 +0100 Subject: [PATCH 10/22] prepared for 3.1.1 --- build-spring-framework/resources/changelog.txt | 6 ++++++ build-spring-framework/resources/readme.txt | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/build-spring-framework/resources/changelog.txt b/build-spring-framework/resources/changelog.txt index 9f5df713380..e2adc3926c1 100644 --- a/build-spring-framework/resources/changelog.txt +++ b/build-spring-framework/resources/changelog.txt @@ -3,6 +3,12 @@ SPRING FRAMEWORK CHANGELOG http://www.springsource.org +Changes in version 3.1.1 (2012-01-16) +------------------------------------- + +* fixed LocalContainerEntityManagerFactoryBean's "packagesToScan" to avoid additional provider scan + + Changes in version 3.1 GA (2011-12-12) -------------------------------------- diff --git a/build-spring-framework/resources/readme.txt b/build-spring-framework/resources/readme.txt index c9ba7af6b37..589ee6635f6 100644 --- a/build-spring-framework/resources/readme.txt +++ b/build-spring-framework/resources/readme.txt @@ -1,5 +1,5 @@ -SPRING FRAMEWORK 3.1 GA (December 2011) ---------------------------------------- +SPRING FRAMEWORK 3.1.1 (January 2012) +------------------------------------- http://www.springsource.org 1. INTRODUCTION From 00ff8fa2ccbaa4f689a74cc65a8bd20eda877484 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller <jhoeller@vmware.com> Date: Wed, 21 Dec 2011 13:35:48 +0100 Subject: [PATCH 11/22] corrected fix for QuartzJobBean to work with Quartz 2.0/2.1 (SPR-8889) --- .../springframework/scheduling/quartz/QuartzJobBean.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/org.springframework.context.support/src/main/java/org/springframework/scheduling/quartz/QuartzJobBean.java b/org.springframework.context.support/src/main/java/org/springframework/scheduling/quartz/QuartzJobBean.java index 7c0ad0e0054..6b193b43d5e 100644 --- a/org.springframework.context.support/src/main/java/org/springframework/scheduling/quartz/QuartzJobBean.java +++ b/org.springframework.context.support/src/main/java/org/springframework/scheduling/quartz/QuartzJobBean.java @@ -79,10 +79,12 @@ public abstract class QuartzJobBean implements Job { static { try { - getSchedulerMethod = JobExecutionContext.class.getMethod("getScheduler"); - getMergedJobDataMapMethod = JobExecutionContext.class.getMethod("getMergedJobDataMap"); + Class jobExecutionContextClass = + QuartzJobBean.class.getClassLoader().loadClass("org.quartz.JobExecutionContext"); + getSchedulerMethod = jobExecutionContextClass.getMethod("getScheduler"); + getMergedJobDataMapMethod = jobExecutionContextClass.getMethod("getMergedJobDataMap"); } - catch (NoSuchMethodException ex) { + catch (Exception ex) { throw new IllegalStateException("Incompatible Quartz API: " + ex); } } From eb31528979e5c6c76012a5ba6fc95308487d8404 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller <jhoeller@vmware.com> Date: Wed, 21 Dec 2011 14:04:37 +0100 Subject: [PATCH 12/22] added "entityInterceptor" property to Hibernate 4 LocalSessionFactoryBean (SPR-8940) --- .../orm/hibernate4/LocalSessionFactoryBean.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBean.java b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBean.java index 986e5e942f6..5af9396b3d1 100644 --- a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBean.java +++ b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBean.java @@ -21,6 +21,7 @@ import java.io.IOException; import java.util.Properties; import javax.sql.DataSource; +import org.hibernate.Interceptor; import org.hibernate.SessionFactory; import org.hibernate.cfg.NamingStrategy; @@ -69,6 +70,8 @@ public class LocalSessionFactoryBean implements FactoryBean<SessionFactory>, Res private Resource[] mappingDirectoryLocations; + private Interceptor entityInterceptor; + private NamingStrategy namingStrategy; private Properties hibernateProperties; @@ -178,6 +181,16 @@ public class LocalSessionFactoryBean implements FactoryBean<SessionFactory>, Res this.mappingDirectoryLocations = mappingDirectoryLocations; } + /** + * Set a Hibernate entity interceptor that allows to inspect and change + * property values before writing to and reading from the database. + * Will get applied to any new Session created by this factory. + * @see org.hibernate.cfg.Configuration#setInterceptor + */ + public void setEntityInterceptor(Interceptor entityInterceptor) { + this.entityInterceptor = entityInterceptor; + } + /** * Set a Hibernate NamingStrategy for the SessionFactory, determining the * physical column and table names given the info in the mapping document. @@ -291,6 +304,10 @@ public class LocalSessionFactoryBean implements FactoryBean<SessionFactory>, Res } } + if (this.entityInterceptor != null) { + sfb.setInterceptor(this.entityInterceptor); + } + if (this.namingStrategy != null) { sfb.setNamingStrategy(this.namingStrategy); } From 1c9fe623f94f7a6c1acb258e19f7e5c884e68c5b Mon Sep 17 00:00:00 2001 From: Juergen Hoeller <jhoeller@vmware.com> Date: Wed, 21 Dec 2011 14:05:11 +0100 Subject: [PATCH 13/22] further post-GA fixes --- build-spring-framework/resources/changelog.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build-spring-framework/resources/changelog.txt b/build-spring-framework/resources/changelog.txt index e2adc3926c1..4d1ae2a935e 100644 --- a/build-spring-framework/resources/changelog.txt +++ b/build-spring-framework/resources/changelog.txt @@ -7,6 +7,8 @@ Changes in version 3.1.1 (2012-01-16) ------------------------------------- * fixed LocalContainerEntityManagerFactoryBean's "packagesToScan" to avoid additional provider scan +* added "entityInterceptor" property to Hibernate 4 LocalSessionFactoryBean +* corrected fix for QuartzJobBean to work with Quartz 2.0/2.1 Changes in version 3.1 GA (2011-12-12) From 392247d6746eb8bd83d2ea38f5126c11b49bbe5f Mon Sep 17 00:00:00 2001 From: Juergen Hoeller <jhoeller@vmware.com> Date: Wed, 21 Dec 2011 15:27:53 +0100 Subject: [PATCH 14/22] Hibernate 4 LocalSessionFactoryBean implements PersistenceExceptionTranslator interface as well (SPR-8952); consistent extending of HibernateExceptionTranslator for Hibernate 3 as well as Hibernate 4 --- .../AbstractSessionFactoryBean.java | 64 +------------------ .../HibernateExceptionTranslator.java | 48 +++++++------- .../HibernateExceptionTranslator.java | 8 ++- .../hibernate4/LocalSessionFactoryBean.java | 4 +- 4 files changed, 38 insertions(+), 86 deletions(-) diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/AbstractSessionFactoryBean.java b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/AbstractSessionFactoryBean.java index 135538e7953..9d712c3aa08 100644 --- a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/AbstractSessionFactoryBean.java +++ b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/AbstractSessionFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,15 +21,11 @@ import javax.sql.DataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hibernate.HibernateException; -import org.hibernate.JDBCException; import org.hibernate.SessionFactory; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; -import org.springframework.dao.DataAccessException; -import org.springframework.dao.support.PersistenceExceptionTranslator; -import org.springframework.jdbc.support.SQLExceptionTranslator; /** * Abstract {@link org.springframework.beans.factory.FactoryBean} that creates @@ -54,8 +50,8 @@ import org.springframework.jdbc.support.SQLExceptionTranslator; * @see org.hibernate.SessionFactory#getCurrentSession() * @see org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor */ -public abstract class AbstractSessionFactoryBean - implements FactoryBean<SessionFactory>, InitializingBean, DisposableBean, PersistenceExceptionTranslator { +public abstract class AbstractSessionFactoryBean extends HibernateExceptionTranslator + implements FactoryBean<SessionFactory>, InitializingBean, DisposableBean { /** Logger available to subclasses */ protected final Log logger = LogFactory.getLog(getClass()); @@ -66,8 +62,6 @@ public abstract class AbstractSessionFactoryBean private boolean exposeTransactionAwareSessionFactory = true; - private SQLExceptionTranslator jdbcExceptionTranslator; - private SessionFactory sessionFactory; @@ -184,23 +178,6 @@ public abstract class AbstractSessionFactoryBean return this.exposeTransactionAwareSessionFactory; } - /** - * Set the JDBC exception translator for the SessionFactory, - * exposed via the PersistenceExceptionTranslator interface. - * <p>Applied to any SQLException root cause of a Hibernate JDBCException, - * overriding Hibernate's default SQLException translation (which is - * based on Hibernate's Dialect for a specific target database). - * @param jdbcExceptionTranslator the exception translator - * @see java.sql.SQLException - * @see org.hibernate.JDBCException - * @see org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator - * @see org.springframework.jdbc.support.SQLStateSQLExceptionTranslator - * @see org.springframework.dao.support.PersistenceExceptionTranslator - */ - public void setJdbcExceptionTranslator(SQLExceptionTranslator jdbcExceptionTranslator) { - this.jdbcExceptionTranslator = jdbcExceptionTranslator; - } - /** * Build and expose the SessionFactory. @@ -269,41 +246,6 @@ public abstract class AbstractSessionFactoryBean } - /** - * Implementation of the PersistenceExceptionTranslator interface, - * as autodetected by Spring's PersistenceExceptionTranslationPostProcessor. - * <p>Converts the exception if it is a HibernateException; - * else returns <code>null</code> to indicate an unknown exception. - * @see org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor - * @see #convertHibernateAccessException - */ - public DataAccessException translateExceptionIfPossible(RuntimeException ex) { - if (ex instanceof HibernateException) { - return convertHibernateAccessException((HibernateException) ex); - } - return null; - } - - /** - * Convert the given HibernateException to an appropriate exception from the - * <code>org.springframework.dao</code> hierarchy. - * <p>Will automatically apply a specified SQLExceptionTranslator to a - * Hibernate JDBCException, else rely on Hibernate's default translation. - * @param ex HibernateException that occured - * @return a corresponding DataAccessException - * @see SessionFactoryUtils#convertHibernateAccessException - * @see #setJdbcExceptionTranslator - */ - protected DataAccessException convertHibernateAccessException(HibernateException ex) { - if (this.jdbcExceptionTranslator != null && ex instanceof JDBCException) { - JDBCException jdbcEx = (JDBCException) ex; - return this.jdbcExceptionTranslator.translate( - "Hibernate operation: " + jdbcEx.getMessage(), jdbcEx.getSQL(), jdbcEx.getSQLException()); - } - return SessionFactoryUtils.convertHibernateAccessException(ex); - } - - /** * Build the underlying Hibernate SessionFactory. * @return the raw SessionFactory (potentially to be wrapped with a diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/HibernateExceptionTranslator.java b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/HibernateExceptionTranslator.java index 8eddeb38c3a..60e298cccf4 100644 --- a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/HibernateExceptionTranslator.java +++ b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/HibernateExceptionTranslator.java @@ -18,6 +18,7 @@ package org.springframework.orm.hibernate3; import org.hibernate.HibernateException; import org.hibernate.JDBCException; + import org.springframework.dao.DataAccessException; import org.springframework.dao.support.PersistenceExceptionTranslator; import org.springframework.jdbc.support.SQLExceptionTranslator; @@ -26,14 +27,15 @@ import org.springframework.jdbc.support.SQLExceptionTranslator; * {@link PersistenceExceptionTranslator} capable of translating {@link HibernateException} * instances to Spring's {@link DataAccessException} hierarchy. * - * <p>When configuring the Spring container via XML, note that this translator is - * automatically used internally by {@link SessionFactoryBean} types. When configuring - * the container with {@code @Configuration} classes, a {@code @Bean} of this type - * must be registered manually. + * <p>Extended by {@link LocalSessionFactoryBean}, so there is no need to declare this + * translator in addition to a {@code LocalSessionFactoryBean}. * + * <p>When configuring the container with {@code @Configuration} classes, a {@code @Bean} + * of this type must be registered manually. + * + * @author Juergen Hoeller * @author Chris Beams * @since 3.1 - * @see SessionFactoryBuilder * @see org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor * @see SessionFactoryUtils#convertHibernateAccessException(HibernateException) * @see SQLExceptionTranslator @@ -42,6 +44,25 @@ public class HibernateExceptionTranslator implements PersistenceExceptionTransla private SQLExceptionTranslator jdbcExceptionTranslator; + + /** + * Set the JDBC exception translator for the SessionFactory, + * exposed via the PersistenceExceptionTranslator interface. + * <p>Applied to any SQLException root cause of a Hibernate JDBCException, + * overriding Hibernate's default SQLException translation (which is + * based on Hibernate's Dialect for a specific target database). + * @param jdbcExceptionTranslator the exception translator + * @see java.sql.SQLException + * @see org.hibernate.JDBCException + * @see org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator + * @see org.springframework.jdbc.support.SQLStateSQLExceptionTranslator + * @see org.springframework.dao.support.PersistenceExceptionTranslator + */ + public void setJdbcExceptionTranslator(SQLExceptionTranslator jdbcExceptionTranslator) { + this.jdbcExceptionTranslator = jdbcExceptionTranslator; + } + + public DataAccessException translateExceptionIfPossible(RuntimeException ex) { if (ex instanceof HibernateException) { return convertHibernateAccessException((HibernateException) ex); @@ -68,21 +89,4 @@ public class HibernateExceptionTranslator implements PersistenceExceptionTransla return SessionFactoryUtils.convertHibernateAccessException(ex); } - /** - * Set the JDBC exception translator for the SessionFactory, - * exposed via the PersistenceExceptionTranslator interface. - * <p>Applied to any SQLException root cause of a Hibernate JDBCException, - * overriding Hibernate's default SQLException translation (which is - * based on Hibernate's Dialect for a specific target database). - * @param jdbcExceptionTranslator the exception translator - * @see java.sql.SQLException - * @see org.hibernate.JDBCException - * @see org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator - * @see org.springframework.jdbc.support.SQLStateSQLExceptionTranslator - * @see org.springframework.dao.support.PersistenceExceptionTranslator - */ - public void setJdbcExceptionTranslator(SQLExceptionTranslator jdbcExceptionTranslator) { - this.jdbcExceptionTranslator = jdbcExceptionTranslator; - } - } diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate4/HibernateExceptionTranslator.java b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate4/HibernateExceptionTranslator.java index 8b025793606..ab263ae3c4e 100644 --- a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate4/HibernateExceptionTranslator.java +++ b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate4/HibernateExceptionTranslator.java @@ -23,7 +23,13 @@ import org.springframework.dao.support.PersistenceExceptionTranslator; /** * {@link PersistenceExceptionTranslator} capable of translating {@link HibernateException} - * instances to Spring's {@link org.springframework.dao.DataAccessException} hierarchy. + * instances to Spring's {@link DataAccessException} hierarchy. + * + * <p>Extended by {@link LocalSessionFactoryBean}, so there is no need to declare this + * translator in addition to a {@code LocalSessionFactoryBean}. + * + * <p>When configuring the container with {@code @Configuration} classes, a {@code @Bean} + * of this type must be registered manually. * * @author Juergen Hoeller * @since 3.1 diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBean.java b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBean.java index 5af9396b3d1..50e161d8f84 100644 --- a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBean.java +++ b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBean.java @@ -53,8 +53,8 @@ import org.springframework.core.io.support.ResourcePatternUtils; * @see #setDataSource * @see #setPackagesToScan */ -public class LocalSessionFactoryBean implements FactoryBean<SessionFactory>, ResourceLoaderAware, - InitializingBean, DisposableBean { +public class LocalSessionFactoryBean extends HibernateExceptionTranslator + implements FactoryBean<SessionFactory>, ResourceLoaderAware, InitializingBean, DisposableBean { private DataSource dataSource; From 391434e089fc50680fc018bc0adaabc6a1a0ab56 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller <jhoeller@vmware.com> Date: Wed, 21 Dec 2011 16:47:30 +0100 Subject: [PATCH 15/22] officially deprecated TopLinkJpaDialect in favor of EclipseLink and Spring's EclipseLinkJpaDialect; updated supported version ranges for EclipseLink and OpenJPA --- .../orm/jpa/vendor/EclipseLinkJpaDialect.java | 6 +++--- .../orm/jpa/vendor/EclipseLinkJpaVendorAdapter.java | 5 +++-- .../springframework/orm/jpa/vendor/OpenJpaDialect.java | 7 +++---- .../orm/jpa/vendor/OpenJpaVendorAdapter.java | 6 +++--- .../orm/jpa/vendor/TopLinkJpaDialect.java | 6 ++++-- .../orm/jpa/vendor/TopLinkJpaVendorAdapter.java | 9 +++++---- 6 files changed, 21 insertions(+), 18 deletions(-) diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/jpa/vendor/EclipseLinkJpaDialect.java b/org.springframework.orm/src/main/java/org/springframework/orm/jpa/vendor/EclipseLinkJpaDialect.java index a3a5005727c..7962f6a715f 100644 --- a/org.springframework.orm/src/main/java/org/springframework/orm/jpa/vendor/EclipseLinkJpaDialect.java +++ b/org.springframework.orm/src/main/java/org/springframework/orm/jpa/vendor/EclipseLinkJpaDialect.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,6 @@ package org.springframework.orm.jpa.vendor; import java.sql.Connection; import java.sql.SQLException; - import javax.persistence.EntityManager; import javax.persistence.PersistenceException; @@ -35,7 +34,8 @@ import org.springframework.transaction.TransactionException; /** * {@link org.springframework.orm.jpa.JpaDialect} implementation for Eclipse - * Persistence Services (EclipseLink). Developed and tested against EclipseLink 1.0. + * Persistence Services (EclipseLink). Developed and tested against EclipseLink + * 1.0 as well as 2.0-2.3. * * <p>By default, this class acquires a EclipseLink transaction to get the JDBC Connection * early. This allows mixing JDBC and JPA/EclipseLink operations in the same transaction. diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/jpa/vendor/EclipseLinkJpaVendorAdapter.java b/org.springframework.orm/src/main/java/org/springframework/orm/jpa/vendor/EclipseLinkJpaVendorAdapter.java index 38439cb5a5b..fcc3afd86ec 100644 --- a/org.springframework.orm/src/main/java/org/springframework/orm/jpa/vendor/EclipseLinkJpaVendorAdapter.java +++ b/org.springframework.orm/src/main/java/org/springframework/orm/jpa/vendor/EclipseLinkJpaVendorAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,7 +30,8 @@ import org.springframework.orm.jpa.JpaDialect; /** * {@link org.springframework.orm.jpa.JpaVendorAdapter} implementation for Eclipse - * Persistence Services (EclipseLink). Developed and tested against EclipseLink 1.0. + * Persistence Services (EclipseLink). Developed and tested against EclipseLink + * 1.0 as well as 2.0-2.3. * * <p>Exposes EclipseLink's persistence provider and EntityManager extension interface, * and supports {@link AbstractJpaVendorAdapter}'s common configuration settings. diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/jpa/vendor/OpenJpaDialect.java b/org.springframework.orm/src/main/java/org/springframework/orm/jpa/vendor/OpenJpaDialect.java index 328f9ce5ddc..c6ba980f127 100644 --- a/org.springframework.orm/src/main/java/org/springframework/orm/jpa/vendor/OpenJpaDialect.java +++ b/org.springframework.orm/src/main/java/org/springframework/orm/jpa/vendor/OpenJpaDialect.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007 the original author or authors. + * Copyright 2002-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,6 @@ package org.springframework.orm.jpa.vendor; import java.sql.Connection; import java.sql.SQLException; - import javax.persistence.EntityManager; import javax.persistence.PersistenceException; @@ -34,8 +33,8 @@ import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionException; /** - * {@link org.springframework.orm.jpa.JpaDialect} implementation for - * Apache OpenJPA. Developed and tested against OpenJPA 0.9.7. + * {@link org.springframework.orm.jpa.JpaDialect} implementation for Apache OpenJPA. + * Developed and tested against OpenJPA 1.1 as well as 2.0/2.1. * * @author Costin Leau * @author Juergen Hoeller diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/jpa/vendor/OpenJpaVendorAdapter.java b/org.springframework.orm/src/main/java/org/springframework/orm/jpa/vendor/OpenJpaVendorAdapter.java index 7253b75b51b..cc3a7d79d37 100644 --- a/org.springframework.orm/src/main/java/org/springframework/orm/jpa/vendor/OpenJpaVendorAdapter.java +++ b/org.springframework.orm/src/main/java/org/springframework/orm/jpa/vendor/OpenJpaVendorAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,8 +29,8 @@ import org.apache.openjpa.persistence.PersistenceProviderImpl; import org.springframework.orm.jpa.JpaDialect; /** - * {@link org.springframework.orm.jpa.JpaVendorAdapter} implementation for - * Apache OpenJPA. Developed and tested against OpenJPA 1.0.0. + * {@link org.springframework.orm.jpa.JpaVendorAdapter} implementation for Apache OpenJPA. + * Developed and tested against OpenJPA 1.1 as well as 2.0/2.1. * * <p>Exposes OpenJPA's persistence provider and EntityManager extension interface, * and supports {@link AbstractJpaVendorAdapter}'s common configuration settings. diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/jpa/vendor/TopLinkJpaDialect.java b/org.springframework.orm/src/main/java/org/springframework/orm/jpa/vendor/TopLinkJpaDialect.java index 42693f59c8a..3cf55ffed0e 100644 --- a/org.springframework.orm/src/main/java/org/springframework/orm/jpa/vendor/TopLinkJpaDialect.java +++ b/org.springframework.orm/src/main/java/org/springframework/orm/jpa/vendor/TopLinkJpaDialect.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,6 @@ package org.springframework.orm.jpa.vendor; import java.sql.Connection; import java.sql.SQLException; - import javax.persistence.EntityManager; import javax.persistence.PersistenceException; @@ -50,7 +49,10 @@ import org.springframework.transaction.TransactionException; * @since 2.0 * @see #setLazyDatabaseTransaction * @see org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy + * @deprecated as of Spring 3.1, in favor of the EclipseLink project and + * Spring's corresponding {@link EclipseLinkJpaDialect} */ +@Deprecated public class TopLinkJpaDialect extends DefaultJpaDialect { private boolean lazyDatabaseTransaction = false; diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/jpa/vendor/TopLinkJpaVendorAdapter.java b/org.springframework.orm/src/main/java/org/springframework/orm/jpa/vendor/TopLinkJpaVendorAdapter.java index d865f89d3ab..573b0a85bff 100644 --- a/org.springframework.orm/src/main/java/org/springframework/orm/jpa/vendor/TopLinkJpaVendorAdapter.java +++ b/org.springframework.orm/src/main/java/org/springframework/orm/jpa/vendor/TopLinkJpaVendorAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,11 +16,9 @@ package org.springframework.orm.jpa.vendor; -import java.util.Map; -import java.util.Properties; import java.util.HashMap; +import java.util.Map; import java.util.logging.Level; - import javax.persistence.EntityManager; import javax.persistence.spi.PersistenceProvider; @@ -42,7 +40,10 @@ import org.springframework.orm.jpa.JpaDialect; * @since 2.0 * @see oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider * @see oracle.toplink.essentials.ejb.cmp3.EntityManager + * @deprecated as of Spring 3.1, in favor of the EclipseLink project and + * Spring's corresponding {@link EclipseLinkJpaVendorAdapter} */ +@Deprecated public class TopLinkJpaVendorAdapter extends AbstractJpaVendorAdapter { private final PersistenceProvider persistenceProvider = new EntityManagerFactoryProvider(); From 2caca29498518ffdd3cc6f4a95e154e41c1ae28e Mon Sep 17 00:00:00 2001 From: Juergen Hoeller <jhoeller@vmware.com> Date: Wed, 21 Dec 2011 16:48:03 +0100 Subject: [PATCH 16/22] deprecated TopLinkJpaDialect, etc --- build-spring-framework/resources/changelog.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build-spring-framework/resources/changelog.txt b/build-spring-framework/resources/changelog.txt index 4d1ae2a935e..5a47c2bde0f 100644 --- a/build-spring-framework/resources/changelog.txt +++ b/build-spring-framework/resources/changelog.txt @@ -6,7 +6,9 @@ http://www.springsource.org Changes in version 3.1.1 (2012-01-16) ------------------------------------- +* officially deprecated TopLinkJpaDialect in favor of EclipseLink and Spring's EclipseLinkJpaDialect * fixed LocalContainerEntityManagerFactoryBean's "packagesToScan" to avoid additional provider scan +* Hibernate 4 LocalSessionFactoryBean implements PersistenceExceptionTranslator interface as well * added "entityInterceptor" property to Hibernate 4 LocalSessionFactoryBean * corrected fix for QuartzJobBean to work with Quartz 2.0/2.1 From 09ac195f0ce6b99b02ada2ea122a6e7bc45d50b0 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller <jhoeller@vmware.com> Date: Thu, 22 Dec 2011 02:33:56 +0100 Subject: [PATCH 17/22] do not insist on a "dataSource" reference being set (SPR-8924) --- .../orm/hibernate4/LocalSessionFactoryBuilder.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBuilder.java b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBuilder.java index 4a94bdcd7a4..23ace2b4015 100644 --- a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBuilder.java +++ b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate4/LocalSessionFactoryBuilder.java @@ -77,6 +77,7 @@ public class LocalSessionFactoryBuilder extends Configuration { /** * Create a new LocalSessionFactoryBuilder for the given DataSource. * @param dataSource the JDBC DataSource that the resulting Hibernate SessionFactory should be using + * (may be <code>null</code>) */ public LocalSessionFactoryBuilder(DataSource dataSource) { this(dataSource, new PathMatchingResourcePatternResolver()); @@ -85,6 +86,7 @@ public class LocalSessionFactoryBuilder extends Configuration { /** * Create a new LocalSessionFactoryBuilder for the given DataSource. * @param dataSource the JDBC DataSource that the resulting Hibernate SessionFactory should be using + * (may be <code>null</code>) * @param classLoader the ClassLoader to load application classes from */ public LocalSessionFactoryBuilder(DataSource dataSource, ClassLoader classLoader) { @@ -94,11 +96,14 @@ public class LocalSessionFactoryBuilder extends Configuration { /** * Create a new LocalSessionFactoryBuilder for the given DataSource. * @param dataSource the JDBC DataSource that the resulting Hibernate SessionFactory should be using + * (may be <code>null</code>) * @param classLoader the ResourceLoader to load application classes from */ public LocalSessionFactoryBuilder(DataSource dataSource, ResourceLoader resourceLoader) { getProperties().put(Environment.CURRENT_SESSION_CONTEXT_CLASS, SpringSessionContext.class.getName()); - getProperties().put(Environment.DATASOURCE, dataSource); + if (dataSource != null) { + getProperties().put(Environment.DATASOURCE, dataSource); + } getProperties().put("hibernate.classLoader.application", resourceLoader.getClassLoader()); this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader); } From 07ddedd7bf50c1015ae7fe7fd74abbf77df693e3 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller <jhoeller@vmware.com> Date: Thu, 22 Dec 2011 02:51:13 +0100 Subject: [PATCH 18/22] Hibernate synchronization properly unbinds Session even in case of afterCompletion exception (SPR-8757) --- .../SpringSessionSynchronization.java | 56 +++++++++++-------- .../SpringSessionSynchronization.java | 14 +++-- 2 files changed, 41 insertions(+), 29 deletions(-) diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/SpringSessionSynchronization.java b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/SpringSessionSynchronization.java index aab75ceb202..240ebcbcc94 100644 --- a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/SpringSessionSynchronization.java +++ b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/SpringSessionSynchronization.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -218,32 +218,40 @@ class SpringSessionSynchronization implements TransactionSynchronization, Ordere } public void afterCompletion(int status) { - if (!this.hibernateTransactionCompletion || !this.newSession) { - // No Hibernate TransactionManagerLookup: apply afterTransactionCompletion callback. - // Always perform explicit afterTransactionCompletion callback for pre-bound Session, - // even with Hibernate TransactionManagerLookup (which only applies to new Sessions). - Session session = this.sessionHolder.getSession(); - // Provide correct transaction status for releasing the Session's cache locks, - // if possible. Else, closing will release all cache locks assuming a rollback. - if (session instanceof SessionImplementor) { - ((SessionImplementor) session).afterTransactionCompletion(status == STATUS_COMMITTED, null); + try { + if (!this.hibernateTransactionCompletion || !this.newSession) { + // No Hibernate TransactionManagerLookup: apply afterTransactionCompletion callback. + // Always perform explicit afterTransactionCompletion callback for pre-bound Session, + // even with Hibernate TransactionManagerLookup (which only applies to new Sessions). + Session session = this.sessionHolder.getSession(); + // Provide correct transaction status for releasing the Session's cache locks, + // if possible. Else, closing will release all cache locks assuming a rollback. + try { + if (session instanceof SessionImplementor) { + ((SessionImplementor) session).afterTransactionCompletion(status == STATUS_COMMITTED, null); + } + } + finally { + // Close the Hibernate Session here if necessary + // (closed in beforeCompletion in case of TransactionManagerLookup). + if (this.newSession) { + SessionFactoryUtils.closeSessionOrRegisterDeferredClose(session, this.sessionFactory); + } + else if (!this.hibernateTransactionCompletion) { + session.disconnect(); + } + } } - // Close the Hibernate Session here if necessary - // (closed in beforeCompletion in case of TransactionManagerLookup). - if (this.newSession) { - SessionFactoryUtils.closeSessionOrRegisterDeferredClose(session, this.sessionFactory); - } - else if (!this.hibernateTransactionCompletion) { - session.disconnect(); + if (!this.newSession && status != STATUS_COMMITTED) { + // Clear all pending inserts/updates/deletes in the Session. + // Necessary for pre-bound Sessions, to avoid inconsistent state. + this.sessionHolder.getSession().clear(); } } - if (!this.newSession && status != STATUS_COMMITTED) { - // Clear all pending inserts/updates/deletes in the Session. - // Necessary for pre-bound Sessions, to avoid inconsistent state. - this.sessionHolder.getSession().clear(); - } - if (this.sessionHolder.doesNotHoldNonDefaultSession()) { - this.sessionHolder.setSynchronizedWithTransaction(false); + finally { + if (this.sessionHolder.doesNotHoldNonDefaultSession()) { + this.sessionHolder.setSynchronizedWithTransaction(false); + } } } diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate4/SpringSessionSynchronization.java b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate4/SpringSessionSynchronization.java index fa49ace3f74..19f47c86fc8 100644 --- a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate4/SpringSessionSynchronization.java +++ b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate4/SpringSessionSynchronization.java @@ -111,12 +111,16 @@ class SpringSessionSynchronization implements TransactionSynchronization, Ordere } public void afterCompletion(int status) { - if (status != STATUS_COMMITTED) { - // Clear all pending inserts/updates/deletes in the Session. - // Necessary for pre-bound Sessions, to avoid inconsistent state. - this.sessionHolder.getSession().clear(); + try { + if (status != STATUS_COMMITTED) { + // Clear all pending inserts/updates/deletes in the Session. + // Necessary for pre-bound Sessions, to avoid inconsistent state. + this.sessionHolder.getSession().clear(); + } + } + finally { + this.sessionHolder.setSynchronizedWithTransaction(false); } - this.sessionHolder.setSynchronizedWithTransaction(false); } } From 4b138e0e508393c74676eef6d2815b1110689e41 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller <jhoeller@vmware.com> Date: Thu, 22 Dec 2011 02:55:00 +0100 Subject: [PATCH 19/22] Hibernate etc --- build-spring-framework/resources/changelog.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build-spring-framework/resources/changelog.txt b/build-spring-framework/resources/changelog.txt index 5a47c2bde0f..93fe13dcdd0 100644 --- a/build-spring-framework/resources/changelog.txt +++ b/build-spring-framework/resources/changelog.txt @@ -9,6 +9,8 @@ Changes in version 3.1.1 (2012-01-16) * officially deprecated TopLinkJpaDialect in favor of EclipseLink and Spring's EclipseLinkJpaDialect * fixed LocalContainerEntityManagerFactoryBean's "packagesToScan" to avoid additional provider scan * Hibernate 4 LocalSessionFactoryBean implements PersistenceExceptionTranslator interface as well +* Hibernate 4 LocalSessionFactoryBean does not insist on a "dataSource" reference being set +* Hibernate synchronization properly unbinds Session even in case of afterCompletion exception * added "entityInterceptor" property to Hibernate 4 LocalSessionFactoryBean * corrected fix for QuartzJobBean to work with Quartz 2.0/2.1 From e0252ad0b12968ac4f4fd5bdc2e6b8fe8447b94a Mon Sep 17 00:00:00 2001 From: Juergen Hoeller <jhoeller@vmware.com> Date: Thu, 22 Dec 2011 03:14:02 +0100 Subject: [PATCH 20/22] "file-encoding" attribute value is being applied correctly (SPR-8024) --- .../config/AbstractPropertyLoadingBeanDefinitionParser.java | 4 ++-- .../context/config/contextNamespaceHandlerTests-location.xml | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/org.springframework.context/src/main/java/org/springframework/context/config/AbstractPropertyLoadingBeanDefinitionParser.java b/org.springframework.context/src/main/java/org/springframework/context/config/AbstractPropertyLoadingBeanDefinitionParser.java index 5476b2136f6..e77ac952b60 100644 --- a/org.springframework.context/src/main/java/org/springframework/context/config/AbstractPropertyLoadingBeanDefinitionParser.java +++ b/org.springframework.context/src/main/java/org/springframework/context/config/AbstractPropertyLoadingBeanDefinitionParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -53,7 +53,7 @@ abstract class AbstractPropertyLoadingBeanDefinitionParser extends AbstractSingl String fileEncoding = element.getAttribute("file-encoding"); if (StringUtils.hasLength(fileEncoding)) { - builder.addPropertyReference("fileEncoding", fileEncoding); + builder.addPropertyValue("fileEncoding", fileEncoding); } String order = element.getAttribute("order"); diff --git a/org.springframework.context/src/test/resources/org/springframework/context/config/contextNamespaceHandlerTests-location.xml b/org.springframework.context/src/test/resources/org/springframework/context/config/contextNamespaceHandlerTests-location.xml index 980835347bc..1b4f07e1104 100644 --- a/org.springframework.context/src/test/resources/org/springframework/context/config/contextNamespaceHandlerTests-location.xml +++ b/org.springframework.context/src/test/resources/org/springframework/context/config/contextNamespaceHandlerTests-location.xml @@ -7,7 +7,8 @@ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd"> <context:property-placeholder - location="classpath*:/org/springframework/context/config/test-*.properties,classpath*:/org/springframework/context/config/empty-*.properties,classpath*:/org/springframework/context/config/missing-*.properties" /> + location="classpath*:/org/springframework/context/config/test-*.properties,classpath*:/org/springframework/context/config/empty-*.properties,classpath*:/org/springframework/context/config/missing-*.properties" + file-encoding="ISO-8859-1"/> <bean id="foo" class="java.lang.String"> <constructor-arg value="${foo}" /> From 103c648a9240ee56e95cc02bfb4ec4ba848b0746 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller <jhoeller@vmware.com> Date: Thu, 22 Dec 2011 03:22:35 +0100 Subject: [PATCH 21/22] added protected "isPersistenceUnitOverrideAllowed()" method to DefaultPersistenceUnitManager (SPR-8925) --- .../DefaultPersistenceUnitManager.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/jpa/persistenceunit/DefaultPersistenceUnitManager.java b/org.springframework.orm/src/main/java/org/springframework/orm/jpa/persistenceunit/DefaultPersistenceUnitManager.java index 2afd92abca2..36d446b81e1 100644 --- a/org.springframework.orm/src/main/java/org/springframework/orm/jpa/persistenceunit/DefaultPersistenceUnitManager.java +++ b/org.springframework.orm/src/main/java/org/springframework/orm/jpa/persistenceunit/DefaultPersistenceUnitManager.java @@ -353,7 +353,7 @@ public class DefaultPersistenceUnitManager } postProcessPersistenceUnitInfo(pui); String name = pui.getPersistenceUnitName(); - if (!this.persistenceUnitInfoNames.add(name)) { + if (!this.persistenceUnitInfoNames.add(name) && !isPersistenceUnitOverrideAllowed()) { StringBuilder msg = new StringBuilder(); msg.append("Conflicting persistence unit definitions for name '").append(name).append("': "); msg.append(pui.getPersistenceUnitRootUrl()).append(", "); @@ -478,7 +478,7 @@ public class DefaultPersistenceUnitManager /** * Hook method allowing subclasses to customize each PersistenceUnitInfo. - * <p>Default implementation delegates to all registered PersistenceUnitPostProcessors. + * <p>The default implementation delegates to all registered PersistenceUnitPostProcessors. * It is usually preferable to register further entity classes, jar files etc there * rather than in a subclass of this manager, to be able to reuse the post-processors. * @param pui the chosen PersistenceUnitInfo, as read from <code>persistence.xml</code>. @@ -494,6 +494,15 @@ public class DefaultPersistenceUnitManager } } + /** + * Return whether an override of a same-named persistence unit is allowed. + * <p>Default is <code>false</code>. May be overridden to return <code>true</code>, + * for example if {@link #postProcessPersistenceUnitInfo} is able to handle that case. + */ + protected boolean isPersistenceUnitOverrideAllowed() { + return false; + } + public PersistenceUnitInfo obtainDefaultPersistenceUnitInfo() { if (this.persistenceUnitInfoNames.isEmpty()) { From f1168ea45354e1e162979f3462549fe4f2b98de5 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller <jhoeller@vmware.com> Date: Thu, 22 Dec 2011 03:25:03 +0100 Subject: [PATCH 22/22] DefaultPersistenceUnitManager etc --- build-spring-framework/resources/changelog.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build-spring-framework/resources/changelog.txt b/build-spring-framework/resources/changelog.txt index 93fe13dcdd0..526cc1fe77c 100644 --- a/build-spring-framework/resources/changelog.txt +++ b/build-spring-framework/resources/changelog.txt @@ -6,8 +6,10 @@ http://www.springsource.org Changes in version 3.1.1 (2012-01-16) ------------------------------------- +* context:property-placeholder's "file-encoding" attribute value is being applied correctly * officially deprecated TopLinkJpaDialect in favor of EclipseLink and Spring's EclipseLinkJpaDialect * fixed LocalContainerEntityManagerFactoryBean's "packagesToScan" to avoid additional provider scan +* added protected "isPersistenceUnitOverrideAllowed()" method to DefaultPersistenceUnitManager * Hibernate 4 LocalSessionFactoryBean implements PersistenceExceptionTranslator interface as well * Hibernate 4 LocalSessionFactoryBean does not insist on a "dataSource" reference being set * Hibernate synchronization properly unbinds Session even in case of afterCompletion exception