From 19aaa292941c5e3256122d300438a2df7b04a6ae Mon Sep 17 00:00:00 2001
From: tdferreira <49493150+tdferreira@users.noreply.github.com>
Date: Tue, 22 Oct 2024 23:36:46 +0200
Subject: [PATCH 1/5] Rename tiles2 to tiles3
---
pom.xml | 32 ++----------------
{tiles2 => tiles3}/pom.xml | 18 ++++++++--
.../tiles3}/RedeployableActionServlet.java | 2 +-
.../apache/struts/tiles3}/TilesPlugin.java | 2 +-
.../struts/tiles3}/TilesPluginContainer.java | 2 +-
.../tiles3}/TilesPluginContainerFactory.java | 2 +-
.../struts/tiles3}/TilesRequestProcessor.java | 2 +-
.../actions/DefinitionDispatcherAction.java | 0
.../actions/ReloadDefinitionsAction.java | 0
.../struts/tiles3}/actions/TilesAction.java | 0
.../tiles3}/commands/TilesPreProcessor.java | 0
.../struts/tiles3}/doc-files/image001.png | Bin
.../struts/tiles3}/doc-files/tilesUML.png | Bin
.../apache/struts/tiles3}/package-info.java | 0
.../tiles3}/preparer/ActionPreparer.java | 0
.../preparer/StrutsPreparerFactory.java | 0
.../struts/tiles3}/preparer/UrlPreparer.java | 0
.../util/PlugInConfigContextAdapter.java | 0
.../src/main/resources/LICENSE.txt | 0
.../src/main/resources/NOTICE.txt | 0
.../apache/struts/tiles3}/chain-config.xml | 4 +--
{tiles2 => tiles3}/src/site/fml/faq.fml | 0
.../site/resources/images/struts-power.gif | Bin
{tiles2 => tiles3}/src/site/site.xml | 0
{tiles2 => tiles3}/src/site/xdoc/examples.xml | 0
{tiles2 => tiles3}/src/site/xdoc/index.xml | 0
.../src/site/xdoc/installation.xml | 0
.../src/site/xdoc/userGuide.xml | 0
.../struts/tiles3}/TestTilesPlugin.java | 6 ++--
.../struts/tiles3}/config/tiles-defs.xml | 4 +--
30 files changed, 29 insertions(+), 45 deletions(-)
rename {tiles2 => tiles3}/pom.xml (86%)
rename {tiles2/src/main/java/org/apache/struts/tiles2 => tiles3/src/main/java/org/apache/struts/tiles3}/RedeployableActionServlet.java (98%)
rename {tiles2/src/main/java/org/apache/struts/tiles2 => tiles3/src/main/java/org/apache/struts/tiles3}/TilesPlugin.java (99%)
rename {tiles2/src/main/java/org/apache/struts/tiles2 => tiles3/src/main/java/org/apache/struts/tiles3}/TilesPluginContainer.java (99%)
rename {tiles2/src/main/java/org/apache/struts/tiles2 => tiles3/src/main/java/org/apache/struts/tiles3}/TilesPluginContainerFactory.java (99%)
rename {tiles2/src/main/java/org/apache/struts/tiles2 => tiles3/src/main/java/org/apache/struts/tiles3}/TilesRequestProcessor.java (99%)
rename {tiles2/src/main/java/org/apache/struts/tiles2 => tiles3/src/main/java/org/apache/struts/tiles3}/actions/DefinitionDispatcherAction.java (100%)
rename {tiles2/src/main/java/org/apache/struts/tiles2 => tiles3/src/main/java/org/apache/struts/tiles3}/actions/ReloadDefinitionsAction.java (100%)
rename {tiles2/src/main/java/org/apache/struts/tiles2 => tiles3/src/main/java/org/apache/struts/tiles3}/actions/TilesAction.java (100%)
rename {tiles2/src/main/java/org/apache/struts/tiles2 => tiles3/src/main/java/org/apache/struts/tiles3}/commands/TilesPreProcessor.java (100%)
rename {tiles2/src/main/java/org/apache/struts/tiles2 => tiles3/src/main/java/org/apache/struts/tiles3}/doc-files/image001.png (100%)
rename {tiles2/src/main/java/org/apache/struts/tiles2 => tiles3/src/main/java/org/apache/struts/tiles3}/doc-files/tilesUML.png (100%)
rename {tiles2/src/main/java/org/apache/struts/tiles2 => tiles3/src/main/java/org/apache/struts/tiles3}/package-info.java (100%)
rename {tiles2/src/main/java/org/apache/struts/tiles2 => tiles3/src/main/java/org/apache/struts/tiles3}/preparer/ActionPreparer.java (100%)
rename {tiles2/src/main/java/org/apache/struts/tiles2 => tiles3/src/main/java/org/apache/struts/tiles3}/preparer/StrutsPreparerFactory.java (100%)
rename {tiles2/src/main/java/org/apache/struts/tiles2 => tiles3/src/main/java/org/apache/struts/tiles3}/preparer/UrlPreparer.java (100%)
rename {tiles2/src/main/java/org/apache/struts/tiles2 => tiles3/src/main/java/org/apache/struts/tiles3}/util/PlugInConfigContextAdapter.java (100%)
rename {tiles2 => tiles3}/src/main/resources/LICENSE.txt (100%)
rename {tiles2 => tiles3}/src/main/resources/NOTICE.txt (100%)
rename {tiles2/src/main/resources/org/apache/struts/tiles2 => tiles3/src/main/resources/org/apache/struts/tiles3}/chain-config.xml (98%)
rename {tiles2 => tiles3}/src/site/fml/faq.fml (100%)
rename {tiles2 => tiles3}/src/site/resources/images/struts-power.gif (100%)
rename {tiles2 => tiles3}/src/site/site.xml (100%)
rename {tiles2 => tiles3}/src/site/xdoc/examples.xml (100%)
rename {tiles2 => tiles3}/src/site/xdoc/index.xml (100%)
rename {tiles2 => tiles3}/src/site/xdoc/installation.xml (100%)
rename {tiles2 => tiles3}/src/site/xdoc/userGuide.xml (100%)
rename {tiles2/src/test/java/org/apache/struts/tiles2 => tiles3/src/test/java/org/apache/struts/tiles3}/TestTilesPlugin.java (98%)
rename {tiles2/src/test/resources/org/apache/struts/tiles2 => tiles3/src/test/resources/org/apache/struts/tiles3}/config/tiles-defs.xml (97%)
diff --git a/pom.xml b/pom.xml
index 67dc514c2..bcb6d4ce0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -382,8 +382,6 @@
4.0.154.15.02.0.9
- 3.0.8
- 1.0.74.13.14.0.42.3.6
@@ -518,7 +516,7 @@
scriptingtaglibtiles
- tiles2
+ tiles3
@@ -1156,32 +1154,6 @@
groovy-jsr223${groovyVersion}
-
- org.apache.tiles
- tiles-api
- ${tilesVersion}
-
-
- org.apache.tiles
- tiles-core
- ${tilesVersion}
-
-
- org.slf4j
- jcl-over-slf4j
-
-
-
-
- org.apache.tiles
- tiles-request-api
- ${tilesRequestVersion}
-
-
- org.apache.tiles
- tiles-request-servlet
- ${tilesRequestVersion}
- ${project.groupId}struts-blank
@@ -1275,7 +1247,7 @@
${project.groupId}
- struts-tiles2
+ struts-tiles3${project.version}
diff --git a/tiles2/pom.xml b/tiles3/pom.xml
similarity index 86%
rename from tiles2/pom.xml
rename to tiles3/pom.xml
index e44973448..aedbb82fc 100644
--- a/tiles2/pom.xml
+++ b/tiles3/pom.xml
@@ -29,12 +29,14 @@
4.0.0
- struts-tiles2
+ struts-tiles3jar
- Struts Tiles 2 integration
+ Struts Tiles 3 integration
- org.apache.struts.tiles2
+ org.apache.struts.tiles3
+ 3.0.8
+ 1.0.7
@@ -60,18 +62,28 @@
org.apache.tilestiles-api
+ ${tiles3Version}org.apache.tilestiles-core
+ ${tiles3Version}
+
+
+ org.slf4j
+ jcl-over-slf4j
+
+ org.apache.tilestiles-request-api
+ ${tilesRequestVersion}org.apache.tilestiles-request-servlet
+ ${tilesRequestVersion}commons-beanutils
diff --git a/tiles2/src/main/java/org/apache/struts/tiles2/RedeployableActionServlet.java b/tiles3/src/main/java/org/apache/struts/tiles3/RedeployableActionServlet.java
similarity index 98%
rename from tiles2/src/main/java/org/apache/struts/tiles2/RedeployableActionServlet.java
rename to tiles3/src/main/java/org/apache/struts/tiles3/RedeployableActionServlet.java
index 0a9ddc661..fb8f61e6b 100644
--- a/tiles2/src/main/java/org/apache/struts/tiles2/RedeployableActionServlet.java
+++ b/tiles3/src/main/java/org/apache/struts/tiles3/RedeployableActionServlet.java
@@ -18,7 +18,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.struts.tiles2;
+package org.apache.struts.tiles3;
import javax.servlet.ServletException;
diff --git a/tiles2/src/main/java/org/apache/struts/tiles2/TilesPlugin.java b/tiles3/src/main/java/org/apache/struts/tiles3/TilesPlugin.java
similarity index 99%
rename from tiles2/src/main/java/org/apache/struts/tiles2/TilesPlugin.java
rename to tiles3/src/main/java/org/apache/struts/tiles3/TilesPlugin.java
index 7c7a7bfd9..e0c5bcdfa 100644
--- a/tiles2/src/main/java/org/apache/struts/tiles2/TilesPlugin.java
+++ b/tiles3/src/main/java/org/apache/struts/tiles3/TilesPlugin.java
@@ -19,7 +19,7 @@
* under the License.
*/
-package org.apache.struts.tiles2;
+package org.apache.struts.tiles3;
import javax.servlet.ServletException;
diff --git a/tiles2/src/main/java/org/apache/struts/tiles2/TilesPluginContainer.java b/tiles3/src/main/java/org/apache/struts/tiles3/TilesPluginContainer.java
similarity index 99%
rename from tiles2/src/main/java/org/apache/struts/tiles2/TilesPluginContainer.java
rename to tiles3/src/main/java/org/apache/struts/tiles3/TilesPluginContainer.java
index e97751ba8..20c20afc7 100644
--- a/tiles2/src/main/java/org/apache/struts/tiles2/TilesPluginContainer.java
+++ b/tiles3/src/main/java/org/apache/struts/tiles3/TilesPluginContainer.java
@@ -19,7 +19,7 @@
* under the License.
*/
-package org.apache.struts.tiles2;
+package org.apache.struts.tiles3;
import java.util.HashMap;
import java.util.Map;
diff --git a/tiles2/src/main/java/org/apache/struts/tiles2/TilesPluginContainerFactory.java b/tiles3/src/main/java/org/apache/struts/tiles3/TilesPluginContainerFactory.java
similarity index 99%
rename from tiles2/src/main/java/org/apache/struts/tiles2/TilesPluginContainerFactory.java
rename to tiles3/src/main/java/org/apache/struts/tiles3/TilesPluginContainerFactory.java
index de5340c47..ab734aff4 100644
--- a/tiles2/src/main/java/org/apache/struts/tiles2/TilesPluginContainerFactory.java
+++ b/tiles3/src/main/java/org/apache/struts/tiles3/TilesPluginContainerFactory.java
@@ -19,7 +19,7 @@
* under the License.
*/
-package org.apache.struts.tiles2;
+package org.apache.struts.tiles3;
import java.util.Collections;
import java.util.List;
diff --git a/tiles2/src/main/java/org/apache/struts/tiles2/TilesRequestProcessor.java b/tiles3/src/main/java/org/apache/struts/tiles3/TilesRequestProcessor.java
similarity index 99%
rename from tiles2/src/main/java/org/apache/struts/tiles2/TilesRequestProcessor.java
rename to tiles3/src/main/java/org/apache/struts/tiles3/TilesRequestProcessor.java
index c470fed04..19f78fcd1 100644
--- a/tiles2/src/main/java/org/apache/struts/tiles2/TilesRequestProcessor.java
+++ b/tiles3/src/main/java/org/apache/struts/tiles3/TilesRequestProcessor.java
@@ -18,7 +18,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.struts.tiles2;
+package org.apache.struts.tiles3;
import java.io.IOException;
diff --git a/tiles2/src/main/java/org/apache/struts/tiles2/actions/DefinitionDispatcherAction.java b/tiles3/src/main/java/org/apache/struts/tiles3/actions/DefinitionDispatcherAction.java
similarity index 100%
rename from tiles2/src/main/java/org/apache/struts/tiles2/actions/DefinitionDispatcherAction.java
rename to tiles3/src/main/java/org/apache/struts/tiles3/actions/DefinitionDispatcherAction.java
diff --git a/tiles2/src/main/java/org/apache/struts/tiles2/actions/ReloadDefinitionsAction.java b/tiles3/src/main/java/org/apache/struts/tiles3/actions/ReloadDefinitionsAction.java
similarity index 100%
rename from tiles2/src/main/java/org/apache/struts/tiles2/actions/ReloadDefinitionsAction.java
rename to tiles3/src/main/java/org/apache/struts/tiles3/actions/ReloadDefinitionsAction.java
diff --git a/tiles2/src/main/java/org/apache/struts/tiles2/actions/TilesAction.java b/tiles3/src/main/java/org/apache/struts/tiles3/actions/TilesAction.java
similarity index 100%
rename from tiles2/src/main/java/org/apache/struts/tiles2/actions/TilesAction.java
rename to tiles3/src/main/java/org/apache/struts/tiles3/actions/TilesAction.java
diff --git a/tiles2/src/main/java/org/apache/struts/tiles2/commands/TilesPreProcessor.java b/tiles3/src/main/java/org/apache/struts/tiles3/commands/TilesPreProcessor.java
similarity index 100%
rename from tiles2/src/main/java/org/apache/struts/tiles2/commands/TilesPreProcessor.java
rename to tiles3/src/main/java/org/apache/struts/tiles3/commands/TilesPreProcessor.java
diff --git a/tiles2/src/main/java/org/apache/struts/tiles2/doc-files/image001.png b/tiles3/src/main/java/org/apache/struts/tiles3/doc-files/image001.png
similarity index 100%
rename from tiles2/src/main/java/org/apache/struts/tiles2/doc-files/image001.png
rename to tiles3/src/main/java/org/apache/struts/tiles3/doc-files/image001.png
diff --git a/tiles2/src/main/java/org/apache/struts/tiles2/doc-files/tilesUML.png b/tiles3/src/main/java/org/apache/struts/tiles3/doc-files/tilesUML.png
similarity index 100%
rename from tiles2/src/main/java/org/apache/struts/tiles2/doc-files/tilesUML.png
rename to tiles3/src/main/java/org/apache/struts/tiles3/doc-files/tilesUML.png
diff --git a/tiles2/src/main/java/org/apache/struts/tiles2/package-info.java b/tiles3/src/main/java/org/apache/struts/tiles3/package-info.java
similarity index 100%
rename from tiles2/src/main/java/org/apache/struts/tiles2/package-info.java
rename to tiles3/src/main/java/org/apache/struts/tiles3/package-info.java
diff --git a/tiles2/src/main/java/org/apache/struts/tiles2/preparer/ActionPreparer.java b/tiles3/src/main/java/org/apache/struts/tiles3/preparer/ActionPreparer.java
similarity index 100%
rename from tiles2/src/main/java/org/apache/struts/tiles2/preparer/ActionPreparer.java
rename to tiles3/src/main/java/org/apache/struts/tiles3/preparer/ActionPreparer.java
diff --git a/tiles2/src/main/java/org/apache/struts/tiles2/preparer/StrutsPreparerFactory.java b/tiles3/src/main/java/org/apache/struts/tiles3/preparer/StrutsPreparerFactory.java
similarity index 100%
rename from tiles2/src/main/java/org/apache/struts/tiles2/preparer/StrutsPreparerFactory.java
rename to tiles3/src/main/java/org/apache/struts/tiles3/preparer/StrutsPreparerFactory.java
diff --git a/tiles2/src/main/java/org/apache/struts/tiles2/preparer/UrlPreparer.java b/tiles3/src/main/java/org/apache/struts/tiles3/preparer/UrlPreparer.java
similarity index 100%
rename from tiles2/src/main/java/org/apache/struts/tiles2/preparer/UrlPreparer.java
rename to tiles3/src/main/java/org/apache/struts/tiles3/preparer/UrlPreparer.java
diff --git a/tiles2/src/main/java/org/apache/struts/tiles2/util/PlugInConfigContextAdapter.java b/tiles3/src/main/java/org/apache/struts/tiles3/util/PlugInConfigContextAdapter.java
similarity index 100%
rename from tiles2/src/main/java/org/apache/struts/tiles2/util/PlugInConfigContextAdapter.java
rename to tiles3/src/main/java/org/apache/struts/tiles3/util/PlugInConfigContextAdapter.java
diff --git a/tiles2/src/main/resources/LICENSE.txt b/tiles3/src/main/resources/LICENSE.txt
similarity index 100%
rename from tiles2/src/main/resources/LICENSE.txt
rename to tiles3/src/main/resources/LICENSE.txt
diff --git a/tiles2/src/main/resources/NOTICE.txt b/tiles3/src/main/resources/NOTICE.txt
similarity index 100%
rename from tiles2/src/main/resources/NOTICE.txt
rename to tiles3/src/main/resources/NOTICE.txt
diff --git a/tiles2/src/main/resources/org/apache/struts/tiles2/chain-config.xml b/tiles3/src/main/resources/org/apache/struts/tiles3/chain-config.xml
similarity index 98%
rename from tiles2/src/main/resources/org/apache/struts/tiles2/chain-config.xml
rename to tiles3/src/main/resources/org/apache/struts/tiles3/chain-config.xml
index 7f17f824f..f5fd29fe3 100644
--- a/tiles2/src/main/resources/org/apache/struts/tiles2/chain-config.xml
+++ b/tiles3/src/main/resources/org/apache/struts/tiles3/chain-config.xml
@@ -212,7 +212,7 @@
className="org.apache.struts.chain.commands.ExecuteForwardCommand"/>
+ className="org.apache.struts.tiles3.commands.TilesPreProcessor"/>
+ className="org.apache.struts.tiles3.commands.TilesPreProcessor"/>
+ "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
+ "http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
From 3ba76a772c9f1dc802fc3abac47879f8c93063c0 Mon Sep 17 00:00:00 2001
From: tdferreira <49493150+tdferreira@users.noreply.github.com>
Date: Tue, 22 Oct 2024 23:39:25 +0200
Subject: [PATCH 2/5] Restore tiles2 module supporting Tiles 2.x
---
pom.xml | 20 +
tiles2/pom.xml | 165 +++++++
.../tiles2/RedeployableActionServlet.java | 92 ++++
.../org/apache/struts/tiles2/TilesPlugin.java | 348 ++++++++++++++
.../struts/tiles2/TilesPluginContainer.java | 156 +++++++
.../tiles2/TilesPluginContainerFactory.java | 114 +++++
.../struts/tiles2/TilesRequestProcessor.java | 262 +++++++++++
.../actions/DefinitionDispatcherAction.java | 125 +++++
.../actions/ReloadDefinitionsAction.java | 88 ++++
.../struts/tiles2/actions/TilesAction.java | 112 +++++
.../tiles2/commands/TilesPreProcessor.java | 114 +++++
.../struts/tiles2/doc-files/image001.gif | Bin 0 -> 1031 bytes
.../struts/tiles2/doc-files/tilesUML.gif | Bin 0 -> 22375 bytes
.../apache/struts/tiles2/package-info.java | 298 ++++++++++++
.../org/apache/struts/tiles2/package.html | 341 ++++++++++++++
.../tiles2/preparer/ActionPreparer.java | 68 +++
.../preparer/StrutsPreparerFactory.java | 55 +++
.../struts/tiles2/preparer/UrlPreparer.java | 87 ++++
.../util/PlugInConfigContextAdapter.java | 393 ++++++++++++++++
tiles2/src/main/resources/LICENSE.txt | 174 +++++++
tiles2/src/main/resources/NOTICE.txt | 10 +
.../org/apache/struts/tiles2/chain-config.xml | 256 ++++++++++
tiles2/src/site/fml/faq.fml | 43 ++
.../site/resources/images/struts-power.gif | Bin 0 -> 1798 bytes
tiles2/src/site/site.xml | 81 ++++
tiles2/src/site/xdoc/examples.xml | 294 ++++++++++++
tiles2/src/site/xdoc/index.xml | 166 +++++++
tiles2/src/site/xdoc/installation.xml | 114 +++++
tiles2/src/site/xdoc/userGuide.xml | 438 ++++++++++++++++++
.../apache/struts/tiles2/TestTilesPlugin.java | 296 ++++++++++++
.../struts/tiles2/config/tiles-defs.xml | 133 ++++++
31 files changed, 4843 insertions(+)
create mode 100644 tiles2/pom.xml
create mode 100644 tiles2/src/main/java/org/apache/struts/tiles2/RedeployableActionServlet.java
create mode 100644 tiles2/src/main/java/org/apache/struts/tiles2/TilesPlugin.java
create mode 100644 tiles2/src/main/java/org/apache/struts/tiles2/TilesPluginContainer.java
create mode 100644 tiles2/src/main/java/org/apache/struts/tiles2/TilesPluginContainerFactory.java
create mode 100644 tiles2/src/main/java/org/apache/struts/tiles2/TilesRequestProcessor.java
create mode 100644 tiles2/src/main/java/org/apache/struts/tiles2/actions/DefinitionDispatcherAction.java
create mode 100644 tiles2/src/main/java/org/apache/struts/tiles2/actions/ReloadDefinitionsAction.java
create mode 100644 tiles2/src/main/java/org/apache/struts/tiles2/actions/TilesAction.java
create mode 100644 tiles2/src/main/java/org/apache/struts/tiles2/commands/TilesPreProcessor.java
create mode 100644 tiles2/src/main/java/org/apache/struts/tiles2/doc-files/image001.gif
create mode 100644 tiles2/src/main/java/org/apache/struts/tiles2/doc-files/tilesUML.gif
create mode 100644 tiles2/src/main/java/org/apache/struts/tiles2/package-info.java
create mode 100644 tiles2/src/main/java/org/apache/struts/tiles2/package.html
create mode 100644 tiles2/src/main/java/org/apache/struts/tiles2/preparer/ActionPreparer.java
create mode 100644 tiles2/src/main/java/org/apache/struts/tiles2/preparer/StrutsPreparerFactory.java
create mode 100644 tiles2/src/main/java/org/apache/struts/tiles2/preparer/UrlPreparer.java
create mode 100644 tiles2/src/main/java/org/apache/struts/tiles2/util/PlugInConfigContextAdapter.java
create mode 100644 tiles2/src/main/resources/LICENSE.txt
create mode 100644 tiles2/src/main/resources/NOTICE.txt
create mode 100644 tiles2/src/main/resources/org/apache/struts/tiles2/chain-config.xml
create mode 100644 tiles2/src/site/fml/faq.fml
create mode 100644 tiles2/src/site/resources/images/struts-power.gif
create mode 100644 tiles2/src/site/site.xml
create mode 100644 tiles2/src/site/xdoc/examples.xml
create mode 100644 tiles2/src/site/xdoc/index.xml
create mode 100644 tiles2/src/site/xdoc/installation.xml
create mode 100644 tiles2/src/site/xdoc/userGuide.xml
create mode 100644 tiles2/src/test/java/org/apache/struts/tiles2/TestTilesPlugin.java
create mode 100644 tiles2/src/test/resources/org/apache/struts/tiles2/config/tiles-defs.xml
diff --git a/pom.xml b/pom.xml
index bcb6d4ce0..ba8ef9151 100644
--- a/pom.xml
+++ b/pom.xml
@@ -516,6 +516,7 @@
scriptingtaglibtiles
+ tiles2tiles3
@@ -812,6 +813,20 @@
+
+ org.apache.maven.plugins
+ maven-source-plugin
+ 3.3.1
+
+
+ attach-sources
+ verify
+
+ jar-no-fork
+
+
+
+
@@ -1245,6 +1260,11 @@
struts-tiles${project.version}
+
+ ${project.groupId}
+ struts-tiles2
+ ${project.version}
+ ${project.groupId}struts-tiles3
diff --git a/tiles2/pom.xml b/tiles2/pom.xml
new file mode 100644
index 000000000..4c9918816
--- /dev/null
+++ b/tiles2/pom.xml
@@ -0,0 +1,165 @@
+
+
+
+
+
+
+ io.github.weblegacy
+ struts-parent
+ 1.4.6-SNAPSHOT
+
+
+ 4.0.0
+ struts-tiles2
+ jar
+ Struts Tiles 2 integration
+ http://struts.apache.org
+
+
+ scm:svn:http://svn.apache.org/repos/asf/struts/struts1/trunk/tiles2/
+ scm:svn:https://svn.apache.org/repos/asf/struts/struts1/trunk/tiles2/
+ http://svn.apache.org/repos/asf/struts/struts1/trunk/tiles2/
+
+
+
+
+ apache-site
+ scp://people.apache.org/www/struts.apache.org/1.x/struts-tiles2
+
+
+
+
+ org.apache.struts.tiles2
+ 2.2.2
+
+
+
+
+
+ src/main/resources
+
+
+
+
+
+ src/test/java
+
+ **/*.xml
+
+
+
+
+
+
+
+ ${project.groupId}
+ struts-core
+ ${project.version}
+
+
+ ${project.groupId}
+ struts-core
+ tests
+ test-jar
+
+
+ jakarta.servlet
+ jakarta.servlet-api
+
+
+ jakarta.servlet.jsp
+ jakarta.servlet.jsp-api
+ test
+
+
+ org.apache.tiles
+ tiles-api
+ ${tiles2Version}
+
+
+ org.apache.tiles
+ tiles-core
+ ${tiles2Version}
+
+
+ org.apache.tiles
+ tiles-api
+ ${tiles2Version}
+
+
+ org.apache.tiles
+ tiles-servlet
+ ${tiles2Version}
+
+
+ commons-beanutils
+ commons-beanutils
+
+
+ io.github.weblegacy
+ commons-chain
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+
+
+ org.slf4j
+ slf4j-api
+
+
+
+ org.slf4j
+ jcl-over-slf4j
+
+
+
+
+
+
+ io.github.weblegacy
+ taglib-maven-plugin
+
+ ${project.basedir}/src/main/resources/META-INF/tld
+ true
+
+
+
+
+
+
+
+ pre-assembly
+
+
+
+ maven-javadoc-plugin
+
+
+ maven-source-plugin
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tiles2/src/main/java/org/apache/struts/tiles2/RedeployableActionServlet.java b/tiles2/src/main/java/org/apache/struts/tiles2/RedeployableActionServlet.java
new file mode 100644
index 000000000..be59be509
--- /dev/null
+++ b/tiles2/src/main/java/org/apache/struts/tiles2/RedeployableActionServlet.java
@@ -0,0 +1,92 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts.tiles2;
+
+import javax.servlet.ServletException;
+
+import org.apache.struts.Globals;
+import org.apache.struts.action.ActionServlet;
+import org.apache.struts.action.RequestProcessor;
+import org.apache.struts.config.ModuleConfig;
+import org.apache.tiles.definition.DefinitionsFactoryException;
+import org.apache.tiles.definition.util.DefinitionsFactoryUtil;
+
+
+/**
+ *
+ * WebLogic (at least v6 and v7) attempts to serialize the TilesRequestProcessor
+ * when re-deploying the Webapp in development mode. The TilesRequestProcessor
+ * is not serializable, and loses the Tiles definitions. This results in
+ * NullPointerException and/or NotSerializableException when using the app after
+ * automatic redeploy.
+ *
+ *
+ * This bug report proposes a workaround for this problem, in the hope it will
+ * help others and maybe motivate an actual fix.
+ *
+ *
+ * The attached class extends the Struts Action servlet and fixes the problem by
+ * reloading the Tiles definitions when they have disappeared.
+ *
+ *
+ * For background discussion see
+ * http://issues.apache.org/bugzilla/show_bug.cgi?id=26322
+ *
+ * @version $Rev$ $Date$
+ * @since 1.2.1
+ */
+public class RedeployableActionServlet extends ActionServlet {
+
+ /**
+ * The request processor for Tiles definitions.
+ */
+ private TilesRequestProcessor tileProcessor;
+
+ /** {@inheritDoc} */
+ protected synchronized RequestProcessor
+ getRequestProcessor(ModuleConfig config) throws ServletException {
+
+ if (tileProcessor != null) {
+ TilesRequestProcessor processor = (TilesRequestProcessor) super.getRequestProcessor(config);
+ return processor;
+ }
+
+ // reset the request processor
+ String requestProcessorKey = Globals.REQUEST_PROCESSOR_KEY
+ + config.getPrefix();
+ getServletContext().removeAttribute(requestProcessorKey);
+
+ // create a new request processor instance
+ TilesRequestProcessor processor = (TilesRequestProcessor) super.getRequestProcessor(config);
+
+ tileProcessor = processor;
+
+ try {
+ // reload Tiles defs
+ DefinitionsFactoryUtil.reloadDefinitionsFactory(
+ getServletContext());
+ } catch (DefinitionsFactoryException e) {
+ e.printStackTrace();
+ }
+
+ return processor;
+ }
+}
diff --git a/tiles2/src/main/java/org/apache/struts/tiles2/TilesPlugin.java b/tiles2/src/main/java/org/apache/struts/tiles2/TilesPlugin.java
new file mode 100644
index 000000000..dc85c8670
--- /dev/null
+++ b/tiles2/src/main/java/org/apache/struts/tiles2/TilesPlugin.java
@@ -0,0 +1,348 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.struts.tiles2;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.struts.action.ActionServlet;
+import org.apache.struts.action.PlugIn;
+import org.apache.struts.action.RequestProcessor;
+import org.apache.struts.chain.ComposableRequestProcessor;
+import org.apache.struts.config.ControllerConfig;
+import org.apache.struts.config.ModuleConfig;
+import org.apache.struts.config.PlugInConfig;
+import org.apache.struts.tiles2.preparer.StrutsPreparerFactory;
+import org.apache.struts.tiles2.util.PlugInConfigContextAdapter;
+import org.apache.struts.util.ModuleUtils;
+import org.apache.struts.util.RequestUtils;
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.TilesException;
+import org.apache.tiles.access.TilesAccess;
+import org.apache.tiles.context.ChainedTilesContextFactory;
+import org.apache.tiles.context.TilesRequestContext;
+import org.apache.tiles.definition.DefinitionsFactory;
+import org.apache.tiles.definition.UrlDefinitionsFactory;
+import org.apache.tiles.factory.KeyedDefinitionsFactoryTilesContainerFactory;
+import org.apache.tiles.factory.TilesContainerFactory;
+import org.apache.tiles.impl.BasicTilesContainer;
+import org.apache.tiles.impl.KeyedDefinitionsFactoryTilesContainer;
+import org.apache.tiles.impl.KeyedDefinitionsFactoryTilesContainer.KeyExtractor;
+import org.apache.tiles.servlet.context.ServletTilesRequestContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.Marker;
+import org.slf4j.MarkerFactory;
+
+/**
+ * Tiles Plugin used to initialize Tiles.
+ * This plugin is to be used with Struts 1.1 in association with
+ * {@link TilesRequestProcessor}.
+ *
+ * This plugin creates one definition factory for each Struts-module. The definition factory
+ * configuration is read first from 'web.xml' (backward compatibility), then it is
+ * overloaded with values found in the plugin property values.
+ *
+ * The plugin changes the Struts configuration by specifying a {@link TilesRequestProcessor} as
+ * request processor. If you want to use your own RequestProcessor,
+ * it should subclass TilesRequestProcessor.
+ *
+ * This plugin can also be used to create one single factory for all modules.
+ * This behavior is enabled by specifying moduleAware=false in each
+ * plugin properties. In this case, the definition factory
+ * configuration file is read by the first Tiles plugin to be initialized. The order is
+ * determined by the order of modules declaration in web.xml. The first module
+ * is always the default one if it exists.
+ * The plugin should be declared in each struts-config.xml file in order to
+ * properly initialize the request processor.
+ *
+ * @version $Rev$ $Date$
+ * @since Struts 1.1
+ */
+// TODO Complete the plugin to be module-aware.
+public class TilesPlugin implements PlugIn {
+
+ /**
+ * Marker for logging of fatal errors.
+ */
+ private final static Marker FATAL = MarkerFactory.getMarker("FATAL");
+
+ /**
+ * Defaults form Tiles 2 configuration in case of a module-aware
+ * configuration.
+ */
+ private static final Map MODULE_AWARE_DEFAULTS =
+ new HashMap();
+
+ /**
+ * Defaults form Tiles 2 configuration in case of a configuration without
+ * modules.
+ */
+ private static final Map NO_MODULE_DEFAULTS =
+ new HashMap();
+
+ static {
+ NO_MODULE_DEFAULTS.put(TilesContainerFactory
+ .CONTEXT_FACTORY_INIT_PARAM,
+ ChainedTilesContextFactory.class.getName());
+ NO_MODULE_DEFAULTS.put(TilesContainerFactory
+ .DEFINITIONS_FACTORY_INIT_PARAM,
+ UrlDefinitionsFactory.class.getName());
+ NO_MODULE_DEFAULTS.put(TilesContainerFactory
+ .PREPARER_FACTORY_INIT_PARAM,
+ StrutsPreparerFactory.class.getName());
+
+ MODULE_AWARE_DEFAULTS.putAll(NO_MODULE_DEFAULTS);
+ MODULE_AWARE_DEFAULTS.put(
+ KeyedDefinitionsFactoryTilesContainerFactory
+ .KEY_EXTRACTOR_CLASS_INIT_PARAM,
+ ModuleKeyExtractor.class.getName());
+ MODULE_AWARE_DEFAULTS.put(TilesContainerFactory
+ .CONTAINER_FACTORY_INIT_PARAM,
+ KeyedDefinitionsFactoryTilesContainerFactory.class.getName());
+ }
+
+ /**
+ * The {@code Log} instance for this class.
+ */
+ private final Logger log =
+ LoggerFactory.getLogger(TilesPlugin.class);
+
+ /**
+ * Is the factory module aware?
+ */
+ protected boolean moduleAware = false;
+
+ /**
+ * The plugin config object provided by the ActionServlet initializing
+ * this plugin.
+ */
+ protected PlugInConfig currentPlugInConfigObject = null;
+
+ /**
+ * The plugin config object adapted to become a context-like object, that
+ * exposes init parameters methods.
+ */
+ protected PlugInConfigContextAdapter currentPlugInConfigContextAdapter = null;
+
+ /**
+ * Get the module aware flag.
+ * @return true: user wants a single factory instance,
+ * false: user wants multiple factory instances (one per module with Struts)
+ */
+ public boolean isModuleAware() {
+ return moduleAware;
+ }
+
+ /**
+ * Set the module aware flag.
+ * This flag is only meaningful if the property tilesUtilImplClassname is not
+ * set.
+ * @param moduleAware true: user wants a single factory instance,
+ * false: user wants multiple factory instances (one per module with Struts)
+ */
+ public void setModuleAware(boolean moduleAware) {
+ this.moduleAware = moduleAware;
+ }
+
+ /**
+ *
Receive notification that the specified module is being
+ * started up.
+ *
+ * @param servlet ActionServlet that is managing all the modules
+ * in this web application.
+ * @param moduleConfig ModuleConfig for the module with which
+ * this plugin is associated.
+ *
+ * @exception ServletException if this PlugIn cannot
+ * be successfully initialized.
+ */
+ public void init(ActionServlet servlet, ModuleConfig moduleConfig)
+ throws ServletException {
+
+ currentPlugInConfigContextAdapter = new PlugInConfigContextAdapter(
+ this.currentPlugInConfigObject, servlet.getServletContext());
+
+ // Set RequestProcessor class
+ this.initRequestProcessorClass(moduleConfig);
+
+ // Initialize Tiles
+ try {
+ TilesPluginContainerFactory factory;
+ TilesContainer container;
+ if (moduleAware) {
+ factory = new TilesPluginContainerFactory();
+ container = TilesAccess.getContainer(
+ currentPlugInConfigContextAdapter);
+ if (container == null) {
+ container = factory.createContainer(
+ currentPlugInConfigContextAdapter);
+ TilesAccess.setContainer(currentPlugInConfigContextAdapter,
+ container);
+ }
+ if (container instanceof TilesPluginContainer) {
+ TilesPluginContainer pluginContainer =
+ (TilesPluginContainer) container;
+ // If we have a definition factory for the current module
+ // prefix then we are trying to re-initialize the same module,
+ // and it is wrong!
+ if (pluginContainer.getProperDefinitionsFactory(moduleConfig
+ .getPrefix()) != null) {
+ throw new ServletException("Tiles definitions factory for module '"
+ + moduleConfig.getPrefix()
+ + "' has already been configured");
+ }
+ DefinitionsFactory defsFactory = factory
+ .createDefinitionsFactory(pluginContainer, currentPlugInConfigContextAdapter);
+ pluginContainer.setDefinitionsFactory(moduleConfig.getPrefix(), defsFactory);
+ } else {
+ log.warn("The created container is not instance of "
+ + "TilesPluginContainer"
+ + " and cannot be configured correctly");
+ }
+ } else {
+ if (currentPlugInConfigContextAdapter.getApplicationScope()
+ .containsKey(TilesAccess.CONTAINER_ATTRIBUTE)) {
+ throw new ServletException(
+ "Tiles container has already been configured");
+ }
+ factory = new TilesPluginContainerFactory();
+ container = factory.createContainer(
+ currentPlugInConfigContextAdapter);
+ TilesAccess.setContainer(currentPlugInConfigContextAdapter,
+ container);
+ }
+ } catch (TilesException e) {
+ log.error(FATAL, "Unable to retrieve tiles factory.", e);
+ throw new IllegalStateException("Unable to instantiate container.");
+ }
+ }
+
+ /**
+ * End plugin.
+ */
+ public void destroy() {
+ try {
+ TilesAccess.setContainer(currentPlugInConfigContextAdapter, null);
+ } catch (TilesException e) {
+ log.warn("Unable to remove tiles container from service.");
+ }
+ }
+
+ /**
+ * Set RequestProcessor to appropriate Tiles {@link RequestProcessor}.
+ * First, check if a RequestProcessor is specified. If yes, check if it extends
+ * the appropriate {@link TilesRequestProcessor} class. If not, set processor class to
+ * TilesRequestProcessor.
+ *
+ * @param config ModuleConfig for the module with which
+ * this plugin is associated.
+ * @throws ServletException On errors.
+ */
+ protected void initRequestProcessorClass(ModuleConfig config)
+ throws ServletException {
+
+ String tilesProcessorClassname = TilesRequestProcessor.class.getName();
+ ControllerConfig ctrlConfig = config.getControllerConfig();
+ String configProcessorClassname = ctrlConfig.getProcessorClass();
+
+ // Check if specified classname exist
+ Class> configProcessorClass;
+ try {
+ configProcessorClass =
+ RequestUtils.applicationClass(configProcessorClassname);
+
+ } catch (ClassNotFoundException ex) {
+ log.error(FATAL, "Can't set TilesRequestProcessor: bad class name '{}'.",
+ configProcessorClassname);
+ throw new ServletException(ex);
+ }
+
+ // Check to see if request processor uses struts-chain. If so,
+ // no need to replace the request processor.
+ if (ComposableRequestProcessor.class.isAssignableFrom(configProcessorClass)) {
+ return;
+ }
+
+ // Check if it is the default request processor or Tiles one.
+ // If true, replace by Tiles' one.
+ if (configProcessorClassname.equals(RequestProcessor.class.getName())
+ || configProcessorClassname.endsWith(tilesProcessorClassname)) {
+
+ ctrlConfig.setProcessorClass(tilesProcessorClassname);
+ return;
+ }
+
+ // Check if specified request processor is compatible with Tiles.
+ Class tilesProcessorClass = TilesRequestProcessor.class;
+ if (!tilesProcessorClass.isAssignableFrom(configProcessorClass)) {
+ // Not compatible
+ String msg =
+ "TilesPlugin : Specified RequestProcessor not compatible with TilesRequestProcessor";
+ log.error(FATAL, msg);
+ throw new ServletException(msg);
+ }
+ }
+
+ /**
+ * Method used by the ActionServlet initializing this plugin.
+ * Set the plugin config object read from module config.
+ * @param plugInConfigObject PlugInConfig.
+ */
+ public void setCurrentPlugInConfigObject(PlugInConfig plugInConfigObject) {
+ this.currentPlugInConfigObject = plugInConfigObject;
+ }
+
+ /**
+ * Extracts the definitions factory key according to the module prefix.
+ */
+ public static class ModuleKeyExtractor implements KeyExtractor {
+
+ /** {@inheritDoc} */
+ public String getDefinitionsFactoryKey(TilesRequestContext request) {
+ String retValue = null;
+
+ if (request instanceof ServletTilesRequestContext) {
+ HttpServletRequest servletRequest =
+ (HttpServletRequest) ((ServletTilesRequestContext) request).getRequest();
+ ModuleConfig config = ModuleUtils.getInstance().getModuleConfig(
+ servletRequest);
+
+ if (config == null) {
+ // ModuleConfig not found in current request. Select it.
+ ModuleUtils.getInstance().selectModule(servletRequest,
+ servletRequest.getSession().getServletContext());
+ config = ModuleUtils.getInstance().getModuleConfig(servletRequest);
+ }
+
+ if (config != null) {
+ retValue = config.getPrefix();
+ }
+ }
+ return retValue;
+ }
+
+ }
+}
diff --git a/tiles2/src/main/java/org/apache/struts/tiles2/TilesPluginContainer.java b/tiles2/src/main/java/org/apache/struts/tiles2/TilesPluginContainer.java
new file mode 100644
index 000000000..fac7945a8
--- /dev/null
+++ b/tiles2/src/main/java/org/apache/struts/tiles2/TilesPluginContainer.java
@@ -0,0 +1,156 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.struts.tiles2;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.struts.config.ModuleConfig;
+import org.apache.struts.util.ModuleUtils;
+import org.apache.tiles.context.TilesRequestContext;
+import org.apache.tiles.Definition;
+import org.apache.tiles.definition.DefinitionsFactory;
+import org.apache.tiles.impl.BasicTilesContainer;
+import org.apache.tiles.locale.LocaleResolver;
+import org.apache.tiles.servlet.context.ServletTilesRequestContext;
+
+public class TilesPluginContainer extends BasicTilesContainer {
+
+ /**
+ * Maps definition factories to their keys.
+ */
+ private final Map key2definitionsFactory =
+ new HashMap<>();
+
+ /**
+ * The locale resolver.
+ */
+ private LocaleResolver localeResolver;
+
+ /**
+ * Sets the locale resolver.
+ *
+ * @param localeResolver the locale resolver for this container.
+ *
+ * @since Struts 1.4.1
+ */
+ void setLocaleResolver(LocaleResolver localeResolver) {
+ this.localeResolver = localeResolver;
+ }
+
+ /**
+ * Returns the locale resolver.
+ *
+ * @return The locale resolve.
+ *
+ * @since Struts 1.4.1
+ */
+ LocaleResolver getLocaleResolverIntern() {
+ return localeResolver;
+ }
+
+ /**
+ * Returns the proper definition factory for the given key, i.e. if the key
+ * is not present, null will be returned.
+ *
+ * @return the definitions factory used by this container. If the key is not
+ * valid, null will be returned.
+ * @param key The key of the needed definitions factory.
+ */
+ public DefinitionsFactory getProperDefinitionsFactory(String key) {
+ DefinitionsFactory retValue = null;
+
+ if (key != null) {
+ retValue = key2definitionsFactory.get(key);
+ }
+
+ return retValue;
+ }
+
+ /**
+ * Set the definitions factory. This method first ensures that the container
+ * has not yet been initialized.
+ *
+ * @param key The key under which the definitions factory is cataloged.
+ * @param definitionsFactory the definitions factory for this instance.
+ * @since 2.1.0
+ */
+ public void setDefinitionsFactory(String key,
+ DefinitionsFactory definitionsFactory) {
+ if (key != null) {
+ key2definitionsFactory.put(key, definitionsFactory);
+ } else {
+ setDefinitionsFactory(definitionsFactory);
+ }
+ }
+
+ @Override
+ public Definition getDefinition(String definitionName,
+ TilesRequestContext request) {
+ Definition retValue = null;
+ String key = getDefinitionsFactoryKey(request);
+ if (key != null) {
+ DefinitionsFactory definitionsFactory =
+ key2definitionsFactory.get(key);
+ if (definitionsFactory != null) {
+ retValue = definitionsFactory.getDefinition(definitionName,
+ request);
+ }
+ }
+ if (retValue == null) {
+ retValue = super.getDefinition(definitionName, request);
+ }
+ return retValue;
+ }
+
+ /**
+ * Returns the definitions factory key.
+ *
+ * @param request The request object.
+ * @return The needed factory key.
+ */
+ protected String getDefinitionsFactoryKey(TilesRequestContext request) {
+ String retValue = null;
+
+ if (request instanceof ServletTilesRequestContext) {
+ HttpServletRequest servletRequest =
+ (HttpServletRequest) ((ServletTilesRequestContext) request).getRequest();
+ ModuleConfig config = ModuleUtils.getInstance().getModuleConfig(
+ servletRequest);
+
+ if (config == null) {
+ // ModuleConfig not found in current request. Select it.
+ ModuleUtils.getInstance().selectModule(servletRequest,
+ servletRequest.getSession().getServletContext());
+ config = ModuleUtils.getInstance().getModuleConfig(servletRequest);
+ }
+
+ if (config != null) {
+ retValue = config.getPrefix();
+ }
+ }
+ return retValue;
+ }
+
+}
\ No newline at end of file
diff --git a/tiles2/src/main/java/org/apache/struts/tiles2/TilesPluginContainerFactory.java b/tiles2/src/main/java/org/apache/struts/tiles2/TilesPluginContainerFactory.java
new file mode 100644
index 000000000..4ae9b95d5
--- /dev/null
+++ b/tiles2/src/main/java/org/apache/struts/tiles2/TilesPluginContainerFactory.java
@@ -0,0 +1,114 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.struts.tiles2;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.tiles.TilesApplicationContext;
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.context.TilesRequestContextFactory;
+import org.apache.tiles.definition.DefinitionsFactory;
+import org.apache.tiles.definition.UnresolvingLocaleDefinitionsFactory;
+import org.apache.tiles.evaluator.AttributeEvaluatorFactory;
+import org.apache.tiles.factory.BasicTilesContainerFactory;
+import org.apache.tiles.factory.TilesContainerFactoryException;
+import org.apache.tiles.locale.LocaleResolver;
+
+public class TilesPluginContainerFactory extends BasicTilesContainerFactory {
+
+ @Override
+ public TilesContainer createContainer(TilesApplicationContext applicationContext) {
+ TilesPluginContainer container = instantiateContainer(applicationContext);
+ TilesRequestContextFactory requestContextFactory =
+ createRequestContextFactory(applicationContext);
+ container.setApplicationContext(applicationContext);
+ LocaleResolver resolver = createLocaleResolver(applicationContext, requestContextFactory);
+ container.setLocaleResolver(resolver);
+ container.setDefinitionsFactory(createDefinitionsFactory(applicationContext, requestContextFactory,
+ resolver));
+ AttributeEvaluatorFactory attributeEvaluatorFactory = createAttributeEvaluatorFactory(
+ applicationContext, requestContextFactory, resolver);
+ container.setAttributeEvaluatorFactory(attributeEvaluatorFactory);
+ container.setPreparerFactory(createPreparerFactory(applicationContext, requestContextFactory));
+ container.setRendererFactory(createRendererFactory(applicationContext, requestContextFactory,
+ container, attributeEvaluatorFactory));
+ return container;
+ }
+
+ @Override
+ protected TilesPluginContainer instantiateContainer(
+ TilesApplicationContext context) {
+ return new TilesPluginContainer();
+ }
+
+ /**
+ * Returns a list containing the URLs to be parsed. By default, it returns a
+ * list containing the URL point to "definitions-config".
+ *
+ * @param applicationContext The Tiles application context.
+ * @param contextFactory The Tiles-Request-Context-Factory
+ * @return The source URLs.
+ * @since Struts 1.4.1
+ */
+ protected List getSourceURLs(TilesApplicationContext applicationContext,
+ TilesRequestContextFactory contextFactory) {
+ String param = applicationContext
+ .getInitParams().get(DefinitionsFactory.DEFINITIONS_CONFIG);
+ if (param == null) {
+ param = applicationContext
+ .getInitParams().get("definitions-config");
+ }
+ if (param == null) {
+ param = "/WEB-INF/tiles.xml";
+ }
+
+ try {
+ return Collections
+ .singletonList(applicationContext.getResource(param));
+ } catch (IOException e) {
+ throw new TilesContainerFactoryException(
+ "Cannot get URL: " + param, e);
+ }
+ }
+
+ /**
+ * Creates the definitions factory. By default it creates a
+ * {@link UnresolvingLocaleDefinitionsFactory} with default dependencies.
+ *
+ * @param container The Tiles-Plugin-Container.
+ * @param applicationContext The Tiles application context.
+ *
+ * @return The definitions factory.
+ * @since Struts 1.4.1
+ */
+ public DefinitionsFactory createDefinitionsFactory(TilesPluginContainer container,
+ TilesApplicationContext applicationContext) {
+ TilesRequestContextFactory requestContextFactory =
+ createRequestContextFactory(applicationContext);
+ LocaleResolver resolver = container.getLocaleResolverIntern();
+ return createDefinitionsFactory(applicationContext, requestContextFactory, resolver);
+ }
+
+}
\ No newline at end of file
diff --git a/tiles2/src/main/java/org/apache/struts/tiles2/TilesRequestProcessor.java b/tiles2/src/main/java/org/apache/struts/tiles2/TilesRequestProcessor.java
new file mode 100644
index 000000000..0fe5b1220
--- /dev/null
+++ b/tiles2/src/main/java/org/apache/struts/tiles2/TilesRequestProcessor.java
@@ -0,0 +1,262 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts.tiles2;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.struts.action.ActionServlet;
+import org.apache.struts.action.RequestProcessor;
+import org.apache.struts.config.ForwardConfig;
+import org.apache.struts.config.ModuleConfig;
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.TilesException;
+import org.apache.tiles.access.TilesAccess;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * RequestProcessor contains the processing logic that the
+ * Struts controller servlet performs as it receives each servlet request from
+ * the container.
+ *
This processor subclasses the Struts RequestProcessor in order to
+ * intercept calls to forward or include. When such calls are done, the Tiles
+ * processor checks if the specified URI is a definition name. If {@code true},
+ * the definition is retrieved and included. If {@code false}, the original URI
+ * is included or a forward is performed.
+ *
Actually, catching is done by overloading the following methods:
+ *
+ *
+ * @since Struts 1.1
+ */
+public class TilesRequestProcessor extends RequestProcessor {
+
+ /**
+ * The {@code Log} instance for this class.
+ */
+ private transient final Logger log =
+ LoggerFactory.getLogger(TilesRequestProcessor.class);
+
+ /**
+ * Initialize this request processor instance.
+ *
+ * @param servlet The ActionServlet we are associated with.
+ * @param moduleConfig The ModuleConfig we are associated with.
+ *
+ * @throws ServletException If an error occurs during initialization.
+ */
+ public void init(ActionServlet servlet, ModuleConfig moduleConfig)
+ throws ServletException {
+
+ super.init(servlet, moduleConfig);
+ }
+
+ /**
+ * Process a Tile definition name. This method tries to process the
+ * parameter {@code definitionName} as a definition name. It returns
+ * {@code true} if a definition has been processed, or {@code false}
+ * otherwise.
+ *
+ * @param definitionName Definition name to insert.
+ * @param request Current page request.
+ * @param response Current page response.
+ *
+ * @return {@code true} if the method has processed uri as a definition
+ * name, [@code false} otherwise.
+ *
+ * @throws IOException If something goes wrong during writing the
+ * definition.
+ * @throws ServletException If something goes wrong during the evaluation
+ * of the definition
+ */
+ protected boolean processTilesDefinition(
+ String definitionName,
+ HttpServletRequest request,
+ HttpServletResponse response)
+ throws IOException, ServletException {
+
+ TilesContainer container = TilesAccess.getContainer(servlet
+ .getServletContext());
+ if (container == null) {
+ log.debug("Tiles container not found, so pass to next command.");
+ return false;
+ }
+
+ boolean retValue = false;
+
+ if (container.isValidDefinition(definitionName, new Object[] { request,
+ response })) {
+ retValue = true;
+ try {
+ container.render(definitionName, new Object[] { request,
+ response });
+ } catch (TilesException e) {
+ throw new ServletException("Cannot render definition '"
+ + definitionName + "'");
+ }
+ } else {
+ // ignore not found
+ log.debug("Cannot find definition '{}'", definitionName);
+ }
+
+ return retValue;
+ }
+
+ /**
+ * Do a forward using request dispatcher. Uri is a valid uri. If response
+ * has already been commited, do an include instead.
+ *
+ * @param uri Uri or Definition name to forward.
+ * @param request Current page request.
+ * @param response Current page response.
+ *
+ * @throws IOException If something goes wrong during writing the
+ * definition.
+ * @throws ServletException If something goes wrong during the evaluation
+ * of the definition
+ */
+ protected void doForward(
+ String uri,
+ HttpServletRequest request,
+ HttpServletResponse response)
+ throws IOException, ServletException {
+
+ if (response.isCommitted()) {
+ this.doInclude(uri, request, response);
+
+ } else {
+ super.doForward(uri, request, response);
+ }
+ }
+
+ /**
+ * Overloaded method from Struts' RequestProcessor. Forward or redirect to
+ * the specified destination by the specified mechanism.
+ *
This method catches the Struts' actionForward call. It checks if the
+ * actionForward is done on a Tiles definition name. If true, process the
+ * definition and insert it. If false, call the original parent's
+ * method.
+ *
+ * @param request The servlet request we are processing.
+ * @param response The servlet response we are creating.
+ * @param forward The ActionForward controlling where we go next.
+ *
+ * @throws IOException if an input/output error occurs.
+ * @throws ServletException if a servlet exception occurs.
+ */
+ protected void processForwardConfig(
+ HttpServletRequest request,
+ HttpServletResponse response,
+ ForwardConfig forward)
+ throws IOException, ServletException {
+
+ // Required by struts contract
+ if (forward == null) {
+ return;
+ }
+
+ log.debug("processForwardConfig({})", forward.getPath());
+
+ // Try to process the definition.
+ if (processTilesDefinition(forward.getPath(),
+ request, response)) {
+ log.debug(" '{}' - processed as definition", forward.getPath());
+ return;
+ }
+
+ log.debug(" '{}' - processed as uri", forward.getPath());
+
+ // forward doesn't contain a definition, let parent do processing
+ super.processForwardConfig(request, response, forward);
+ }
+
+ /**
+ * Catch the call to a module relative forward. If the specified uri is a
+ * tiles definition name, insert it. Otherwise, parent processing is
+ * called. Do a module relative forward to specified uri using request
+ * dispatcher. Uri is relative to the current module. The real uri is
+ * computed by prefixing the module name.
+ *
This method is used internally and is not part of the public
+ * API. It is advised to not use it in subclasses.
+ *
+ * @param uri Module-relative URI to forward to.
+ * @param request Current page request.
+ * @param response Current page response.
+ *
+ * @throws IOException If something goes wrong during writing the
+ * definition.
+ * @throws ServletException If something goes wrong during the evaluation
+ * of the definition
+ *
+ * @since Struts 1.1
+ */
+ protected void internalModuleRelativeForward(
+ String uri,
+ HttpServletRequest request,
+ HttpServletResponse response)
+ throws IOException, ServletException {
+
+ if (processTilesDefinition(uri, request, response)) {
+ return;
+ }
+
+ super.internalModuleRelativeForward(uri, request, response);
+ }
+
+ /**
+ * Do a module relative include to specified uri using request dispatcher.
+ * Uri is relative to the current module. The real uri is computed by
+ * prefixing the module name.
+ *
This method is used internally and is not part of the public
+ * API. It is advised to not use it in subclasses.
+ *
+ * @param uri Module-relative URI to forward to.
+ * @param request Current page request.
+ * @param response Current page response.
+ *
+ * @throws IOException If something goes wrong during writing the
+ * definition.
+ * @throws ServletException If something goes wrong during the evaluation
+ * of the definition
+ *
+ * @since Struts 1.1
+ */
+ protected void internalModuleRelativeInclude(
+ String uri,
+ HttpServletRequest request,
+ HttpServletResponse response)
+ throws IOException, ServletException {
+
+ if (processTilesDefinition(uri, request, response)) {
+ return;
+ }
+
+ super.internalModuleRelativeInclude(uri, request, response);
+ }
+}
\ No newline at end of file
diff --git a/tiles2/src/main/java/org/apache/struts/tiles2/actions/DefinitionDispatcherAction.java b/tiles2/src/main/java/org/apache/struts/tiles2/actions/DefinitionDispatcherAction.java
new file mode 100644
index 000000000..d65035a20
--- /dev/null
+++ b/tiles2/src/main/java/org/apache/struts/tiles2/actions/DefinitionDispatcherAction.java
@@ -0,0 +1,125 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.struts.tiles2.actions;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.struts.action.Action;
+import org.apache.struts.action.ActionForm;
+import org.apache.struts.action.ActionForward;
+import org.apache.struts.action.ActionMapping;
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.access.TilesAccess;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
An Action that dispatches to a Tiles Definition
+ * that is named by the request parameter whose name is specified
+ * by the parameter property of the corresponding
+ * ActionMapping.
+ * This action is useful in following situations:
+ *
+ *
To associate an Url to a definition
+ *
To use Struts <html:link> tag on a definition
+ *
+ *
To configure the use of this action in your
+ * struts-config.xml file, create an entry like this:
which will use the value of the request parameter named "def"
+ * to pick the appropriate definition name.
+ *
The value for success doesn't matter. The forward will forward to
+ * appropriate definition.
+ *
The value for error should denote a valid jsp path or definition name.
+ *
+ * @version $Rev$ $Date$
+ */
+public class DefinitionDispatcherAction extends Action {
+
+ /**
+ * The {@code Log} instance for this class.
+ */
+ private transient final Logger log =
+ LoggerFactory.getLogger(DefinitionDispatcherAction.class);
+
+ /**
+ * Process the specified HTTP request, and create the corresponding HTTP
+ * response (or forward to another web component that will create it),
+ * with provision for handling exceptions thrown by the business logic.
+ *
+ * @param mapping The ActionMapping used to select this instance
+ * @param form The optional ActionForm bean for this request (if any)
+ * @param request The HTTP request we are processing
+ * @param response The HTTP response we are creating
+ *
+ * @throws Exception if the application business logic throws
+ * an exception
+ * @return The forward object..
+ * @since Struts 1.1
+ */
+ public ActionForward execute(
+ ActionMapping mapping,
+ ActionForm form,
+ HttpServletRequest request,
+ HttpServletResponse response)
+ throws Exception {
+
+ // Identify the request parameter containing the method name
+ // If none defined, use "def"
+ String parameter = mapping.getParameter();
+ if (parameter == null) {
+ parameter = "def";
+ }
+
+ // Identify the method name to be dispatched to
+ String name = request.getParameter(parameter);
+ if (name == null) {
+ log.error("Can't get parameter '{}'.", parameter);
+
+ return mapping.findForward("error");
+ }
+
+ // Try to dispatch to requested definition
+ // Read definition from factory, but we can create it here.
+ TilesContainer container = TilesAccess.getContainer(request
+ .getSession().getServletContext());
+ if (container != null
+ && container.isValidDefinition(name, new Object[] { request,
+ response })) {
+ container.render(name, new Object[] { request, response });
+ } else {
+ log.error("Can't get definition '{}'.", name);
+ return mapping.findForward("error");
+ }
+
+ return mapping.findForward("success");
+ }
+}
\ No newline at end of file
diff --git a/tiles2/src/main/java/org/apache/struts/tiles2/actions/ReloadDefinitionsAction.java b/tiles2/src/main/java/org/apache/struts/tiles2/actions/ReloadDefinitionsAction.java
new file mode 100644
index 000000000..323aa7c17
--- /dev/null
+++ b/tiles2/src/main/java/org/apache/struts/tiles2/actions/ReloadDefinitionsAction.java
@@ -0,0 +1,88 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+package org.apache.struts.tiles2.actions;
+
+import java.io.PrintWriter;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.struts.action.Action;
+import org.apache.struts.action.ActionForm;
+import org.apache.struts.action.ActionForward;
+import org.apache.struts.action.ActionMapping;
+import org.apache.tiles.definition.DefinitionsFactoryException;
+import org.apache.tiles.definition.util.DefinitionsFactoryUtil;
+
+/**
+ *
A standard Action that calls the
+ * reload() method of our controller servlet to
+ * reload its configuration information from the configuration
+ * files (which have presumably been updated) dynamically.
+ *
+ * @version $Rev$ $Date$
+ */
+
+public class ReloadDefinitionsAction extends Action {
+
+ /**
+ * Process the specified HTTP request, and create the corresponding HTTP
+ * response (or forward to another web component that will create it),
+ * with provision for handling exceptions thrown by the business logic.
+ *
+ * @param mapping The ActionMapping used to select this instance
+ * @param form The optional ActionForm bean for this request (if any)
+ * @param request The HTTP request we are processing
+ * @param response The HTTP response we are creating
+ *
+ * @throws Exception if the application business logic throws
+ * an exception
+ * @return The forward object.
+ * @since Struts 1.1
+ */
+ public ActionForward execute(ActionMapping mapping,
+ ActionForm form,
+ HttpServletRequest request,
+ HttpServletResponse response)
+ throws Exception {
+ response.setContentType("text/plain");
+ PrintWriter writer = response.getWriter();
+
+ try {
+ ServletContext context = getServlet().getServletContext();
+ DefinitionsFactoryUtil.reloadDefinitionsFactory(context);
+ writer.println("OK");
+ } catch (DefinitionsFactoryException e) {
+ writer.println("FAIL - " + e.toString());
+ getServlet().log("ReloadAction", e);
+ }
+
+ writer.flush();
+ writer.close();
+
+ return (null);
+
+ }
+
+}
diff --git a/tiles2/src/main/java/org/apache/struts/tiles2/actions/TilesAction.java b/tiles2/src/main/java/org/apache/struts/tiles2/actions/TilesAction.java
new file mode 100644
index 000000000..ae7f6da25
--- /dev/null
+++ b/tiles2/src/main/java/org/apache/struts/tiles2/actions/TilesAction.java
@@ -0,0 +1,112 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.struts.tiles2.actions;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.struts.action.Action;
+import org.apache.struts.action.ActionForm;
+import org.apache.struts.action.ActionForward;
+import org.apache.struts.action.ActionMapping;
+import org.apache.tiles.AttributeContext;
+import org.apache.tiles.access.TilesAccess;
+
+/**
+ * Base class for Tiles Actions.
+ * This class has the same role as Struts Action. It provides a method execute(...)
+ * called when action is invoked. The difference is, that the execute() method takes
+ * an additional parameter : tile context.
+ * This class extends Struts Action. Subclasses should override
+ * execute(AttributeContext ...) method instead of Struts
+ * execute(ActionMapping ...) method.
+ * @version $Rev$ $Date$
+ */
+public abstract class TilesAction extends Action {
+
+ /**
+ * Original Struts Action's method.
+ * Retrieve current Tile context and call TilesAction execute method.
+ * Do not overload this method!
+ *
+ * @param mapping The ActionMapping used to select this instance.
+ * @param form The optional ActionForm bean for this request (if any).
+ * @param request The HTTP request we are processing.
+ * @param response The HTTP response we are creating.
+ *
+ * @throws Exception if the application business logic throws
+ * an exception
+ * @return The forward object.
+ * @since Struts 1.1
+ */
+ public ActionForward execute(
+ ActionMapping mapping,
+ ActionForm form,
+ HttpServletRequest request,
+ HttpServletResponse response)
+ throws Exception {
+
+ // Try to retrieve tile context
+ AttributeContext context = TilesAccess.getContainer(
+ request.getSession().getServletContext()).getAttributeContext(
+ new Object[] { request, response });
+ if (context == null) {
+ throw new ServletException(
+ "Can't find Tile context for '"
+ + this.getClass().getName()
+ + "'. TilesAction subclasses must be called from a Tile");
+ }
+
+ return this.execute(context, mapping, form, request, response);
+ }
+
+ /**
+ * Process the specified HTTP request and create the corresponding HTTP
+ * response (or forward to another web component that will create it),
+ * with provision for handling exceptions thrown by the business logic.
+ *
+ * Override this method to provide functionality.
+ *
+ * @param context The current Tile context, containing Tile attributes.
+ * @param mapping The ActionMapping used to select this instance.
+ * @param form The optional ActionForm bean for this request (if any).
+ * @param request The HTTP request we are processing.
+ * @param response The HTTP response we are creating.
+ *
+ * @throws Exception if the application business logic throws
+ * an exception
+ * @return The forward object.
+ * @since Struts 1.1
+ */
+ public ActionForward execute(
+ AttributeContext context,
+ ActionMapping mapping,
+ ActionForm form,
+ HttpServletRequest request,
+ HttpServletResponse response)
+ throws Exception {
+
+ return null;
+ }
+
+}
diff --git a/tiles2/src/main/java/org/apache/struts/tiles2/commands/TilesPreProcessor.java b/tiles2/src/main/java/org/apache/struts/tiles2/commands/TilesPreProcessor.java
new file mode 100644
index 000000000..ccffcab21
--- /dev/null
+++ b/tiles2/src/main/java/org/apache/struts/tiles2/commands/TilesPreProcessor.java
@@ -0,0 +1,114 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts.tiles2.commands;
+
+import org.apache.commons.chain.Command;
+import org.apache.struts.chain.contexts.ServletActionContext;
+import org.apache.struts.config.ForwardConfig;
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.access.TilesAccess;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Command class intended to perform responsibilities of the
+ * TilesRequestProcessor in Struts 1.1. Does not actually dispatch requests,
+ * but simply prepares the chain context for a later forward as appropriate.
+ * Should be added to a chain before something which would handle a
+ * conventional ForwardConfig.
+ *
+ *
This class will never have any effect on the chain unless a
+ * {@code TilesDefinitionFactory} can be found; however it does not consider
+ * the absence of a definition factory to be a fatal error; the command simply
+ * returns false and lets the chain continue.
+ *
+ *
To initialize the {@code TilesDefinitionFactory}, use
+ * {@code org.apache.struts.chain.commands.legacy.TilesPlugin}. This class is a
+ * simple extension to {@code org.apache.struts.tiles2.TilesPlugin} which
+ * simply does not interfere with your choice of {@code RequestProcessor}
+ * implementation.
+ */
+public class TilesPreProcessor implements Command {
+
+
+ // ------------------------------------------------------ Instance Variables
+
+
+ /**
+ * The {@code Log} instance for this class.
+ */
+ private final Logger log =
+ LoggerFactory.getLogger(TilesPreProcessor.class);
+
+ // ---------------------------------------------------------- Public Methods
+
+
+ /**
+ * If the current {@code ForwardConfig} is using "tiles", perform necessary
+ * pre-processing to set up the {@code TilesContext} and substitute a new
+ * {@code ForwardConfig} which is understandable to a
+ * {@code RequestDispatcher}.
+ *
+ *
Note that if the command finds a previously existing
+ * {@code AttributeContext} in the request, then it infers that it has been
+ * called from within another tile, so instead of changing the
+ * {@code ForwardConfig} in the chain {@code Context}, the command uses
+ * {@code RequestDispatcher} to include the tile, and returns
+ * true, indicating that the processing chain is complete.
+ *
+ * @param sacontext The {@code Context} for the current request
+ *
+ * @throws Exception If something goes wrong.
+ *
+ * @return {@code false} in most cases, but true if we determine
+ * that we're processing in "include" mode.
+ */
+ public boolean execute(ServletActionContext sacontext) throws Exception {
+
+ // Is there a Tiles Definition to be processed?
+ ForwardConfig forwardConfig = sacontext.getForwardConfig();
+ if (forwardConfig == null || forwardConfig.getPath() == null) {
+ // this is not a serious error, so log at low priority
+ log.debug("No forwardConfig or no path, so pass to next command.");
+ return (false);
+ }
+
+
+ TilesContainer container = TilesAccess.getContainer(sacontext
+ .getContext());
+ if (container == null) {
+ log.debug("Tiles container not found, so pass to next command.");
+ return false;
+ }
+
+ if (container.isValidDefinition(forwardConfig.getPath(), new Object[] {
+ sacontext.getRequest(), sacontext.getResponse() })) {
+ container.render(forwardConfig.getPath(), new Object[] {
+ sacontext.getRequest(), sacontext.getResponse() });
+ sacontext.setForwardConfig(null);
+ } else {
+ // ignore not found
+ log.debug("Cannot find definition '{}'", forwardConfig.getPath());
+ }
+
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/tiles2/src/main/java/org/apache/struts/tiles2/doc-files/image001.gif b/tiles2/src/main/java/org/apache/struts/tiles2/doc-files/image001.gif
new file mode 100644
index 0000000000000000000000000000000000000000..f675c127c8a11f34a2d225faf336a291148fa253
GIT binary patch
literal 1031
zcmV+i1o-<$Nk%w1VU_@{0CxZ}A^sXuZ)S9NVRB_UAWdmwa&L2QW^^D=W@c$)WdI@h
z1OWg5001ll00ID!0I2|i0000000000|IGjY|Nof*0s{d80|5d91OF(x-2O1iNvpjW
z0x`P(U?`4cX`X1RuA;)ea4gTX=hk?x@8`|`z#z;gEEM5;SLDZ{O
zn%#Pr-LF^}9-DXNvzitT%-rj7Hvosx<8ltEZpVw;19u*R9fW~yb%cn1Ol@$Fg^_`h
zf{=84j7ETzmxGmqg`Ja`V0t5olAxogqpGAwo2!(whl{eWu%;oMqK21`wuhmZxIbyd
z$j8XI%FCq9&WzB}c+=Et*4Jm*+Iij7+}~c|;#%b8R_Ewk8SU=x@bU5vYy|fA`1$(#
z{Qds_00RmPC}2aqfd~^ST*we$L0v-{N}Ncs;=P9lEo$7zQU4#t83HIiZyEQ{r~)3<`RHN;iuPn1P)~qebgn`
z(|aMX=U_(=#x1umN-Cop}04q>_9RG-Q%C2FlW)2S#Y<
zp?>-Y=%W2BSXPmc`V(iRUaI*drjgdUDX05f3MxOMj_Q%8K$?nAsj6OtDy6Lwz-p|s
zwpy#Ix0;&ksJnvNE2qC=8f>M*LR##i#~PY!psvgE+3cOq&Kd2S)3RADn%9z>`PE|2Tp*shEZ%_Hx;^wwL!tLvDdPQFd-%WoM!D8@x>lIV{d525MDAdnogS!(_wn^Y@nHHpa*
z$HL0YsvuJ1$w`dt%3`bJKU7OWq{XvEaFcYuEb^8Xj){}bf(8w3J-9V@W>p>q%r00sgeKmZg7fB^w;
zAOHXY06_o{2ml5FARqt~1b~46a1a0h1^~eT5EuXk10Y}k6byiY0dO$j)gKT706_p?
z$g5)j6as)j0PxpXPyi4L06_s@C;$QlK%oE_6aa?;05AX$1^~eTU>E=b13+N_7z_Z1
z0RV6S5Doyr0bn=)0tZ0h02mwqhXVir5b$3*An?B+Am~3+5F7w{%@PO%fq)<|5Cj2&
zpg<4|2!aDauez_|*8v8BARrJF1cHG;@K*<55D@%N3I>B9U=S1xf`LJBFzB^NAmpDa
z7y^PoKu`z>1_8k#px4TQ(0}$|C
This example inserts the specified page, passing it the attributes. Attributes
+ * are stored in a Tiles context which is passed to the inserted pag and
+ * can then be accesssed by their names.
+ *
+ *
Retrieve an attribute value as String
+ *
<tiles:getAsString name="title" />
+ *
This example retrieves the value of the attribute "title" and prints it as a String in the current output stream. The method toString() is applied on the attribute value, allowing to pass any kind of object as value.
+ *
+ *
Insert Tiles referenced by an attribute
+ *
<tiles:insert attribute='menu' />
+ *
This inserts the Tiles referenced by the attribute "menu" value. The
+ * specified attribute value is first retrieved from current Tiles's context,
+ * and then the value is used as a page target to insert.
+ *
+ *
Classic Layout
+ *
This example is a layout assembling a page in the classic header-footer-menu-body
+ * fashion.
The layout is declared in a JSP page (ex: /layouts/classicLayout.jsp).
+ * It can be used in conjunction with the tag described in "Insert
+ * a page passing some attributes".
+ *
+ *
Definitions
+ *
A definition associates a logical name with the URL of a Tiles to be inserted
+ * and some attribute values. A definition doesn't insert the Tiles. This is
+ * done later using the definition name. A definition name can be inserted
+ * as often as you want in your site, making it easy to reuse a Tiles.
+ *
A definition can extend another definition and overload some attributes
+ * or add new ones. This makes easy factorization of definitions differing
+ * by some attributes. For example, you can define a master definition declaring
+ * the main header, menu, footer, and a default title. Then let each of your
+ * page definitions extend this master definition and overload the title and
+ * the body.
+ *
Definitions can be declared in a JSP page, or in one or more centralized
+ * files. To enable the definitions from centralized files, you need to initialize
+ * the "definitions factory" which will parse the definitions from the files
+ * and provide them to the Tiles framework.
+ *
+ *
Enabling Definition Factory
+ *
To enable Tiles definitions described in one or more files, you need to write these files and to initialize the definition factory.
+ *
Initialization is different depending on the Struts version you use,
+ * or if you do not use Struts at all.
+ *
+ *
Struts1.1
+ *
Use the Tiles plug-in to enable Tiles definitions. This plug-in creates
+ * the definition factory and passese it a configuration object populated
+ * with parameters. Parameters can be specified in the web.xml file or
+ * as plug-in parameters. The plug-in first reads parameters from web.xml,
+ * and then overloads them with the ones found in the plug-in. All parameters
+ * are optional and can be omitted. The plug-in should be declared in each
+ * struts-config file:
Specify configuration file names. There can be several comma separated file names (default: ?? )
+ *
+ *
+ *
definitions-parser-validate: (optional)
+ *
+ *
Specify if XML parser should validate the Tiles configuration
+ * file
+ *
+ *
true : validate. DTD should be specified in file header (default)
+ *
false : no validation
+ *
+ *
+ *
+ *
+ *
+ *
moduleAware: (optional)
+ *
+ *
Specify if the Tiles definition factory is module aware. If true (default),
+ * there will be one factory for each Struts module.
+ * If false, there will be one common factory for all module. In this later case,
+ * it is still needed to declare one plugin per module. The factory will be
+ * initialized with parameters found in the first initialized plugin (generally the
+ * one associated with the default module).
+ *
+ *
true : Tiles framework is module aware
+ *
false :Tiles framework has one single factoy shared among modules (default)
+ *
+ *
+ *
+ *
+ *
+ *
tilesUtilImplClassname: (optional - for advanced user)
+ *
+ *
Specify The classname of the TilesUtil implementation to use. The specified class should
+ * be a subclass of TilesUtilStrutsImpl. This option disable the moduleAware option.
+ *
+ * Specifying "TilesUtilStrutsImpl" is equivalent to moduleAware = false.
+ *
+ * Specifying "TilesUtilStrutsModuleImpl" is equivalent to moduleAware = true.
+ * This option is taken into account only once, when it is first encountered. To avoid problems,
+ * it is advice to specify the same values in all TilesPlugin declaration.
+ *
+ *
+ *
+ *
+ *
+ *
+ *
The TilesPlugin class creates one definition factory for each struts module.
+ *
+ *
+ * If the flag moduleAware is false, only one shared factory is created for all modules.
+ * In this later case, the factory is initialized with parameters found in the first plugin.
+ * The plugins should be declared in all modules, and the moduleAware flag should be
+ * the same for the entire application.
+ *
+ * Paths found in Tiles definitions are relative to the main context.
+ *
You don't need to specify a TilesRequestProcessor, this is automatically
+ * done by the plug-in. If, however, you want to specify your own RequestProcessor,
+ * it should extend the TilesRequestProcessor. The plug-in checks this
+ * constraint.
+ *
+ *
Struts1.0.x
+ *
You need to use a special servlet extending the Struts servlet. This is specified in the web.xml file of your application:
+ *
+ * <servlet>
+ * <servlet-name>action</servlet-name>
+ * <servlet-class>org.apache.struts.tiles.ActionComponentServlet</servlet-class>
+ * <!-- Tiles Servlet parameter
+ * Specify configuration file names. There can be several comma
+ * separated file names
+ * -->
+ * <init-param>
+ * <param-name>definitions-config</param-name>
+ * <param-value>/WEB-INF/tiles-defs.xml</param-value>
+ * </init-param>
+ * <!-- Tiles Servlet parameter
+ * Specify if XML parser should validate the Tiles configuration file(s).
+ * true : validate. DTD should be specified in file header.
+ * false : no validation
+ * -->
+ * <init-param>
+ * <param-name>definitions-parser-validate</param-name>
+ * <param-value>true</param-value>
+ * </init-param>
+ * ...
+ * </servlet>
+ *
+ *
Without Struts
+ *
Tiles can be used without Struts. To initialize the definition factory, you can use the provided servlet. Declare it in the web.xml file of your application:
<!-- Definitions for Tiles documentation --> <tiles-definitions>
+ *
+ * <!-- ========================================================== -->
+ * <!-- Master definition -->
+ * <!-- ========================================================== -->
+ * <!-- Main page layout used as a root for other page definitions -->
+ *
+ * <definition name="site.mainLayout" path="/layouts/classicLayout.jsp">
+ * <put name="title" value="Tiles Blank Site" />
+ * <put name="header" value="/tiles/common/header.jsp" />
+ * <put name="menu" value="site.menu.bar" />
+ * <put name="footer" value="/tiles/common/footer.jsp" />
+ * <put name="body" value="/tiles/body.jsp" />
+ * </definition>
+ *
+ * <!-- ========================================================== -->
+ * <!-- Index page definition -->
+ * <!-- ========================================================== -->
+ * <!-- This definition inherits from the main definition.
+ * It overloads the page title and the body used.
+ * Use the same mechanism to define new pages sharing common
+ * properties (here header, menu, footer, layout)
+ * -->
+ *
+ * <definition name="site.index.page" extends="site.mainLayout" >
+ * <put name="title" value="Tiles Blank Site Index" />
+ * <put name="body" value="/tiles/body.jsp" />
+ * </definition>
</tiles-definition>
+ *
+ *
Debugging
+ *
To debug a page made of Tiles, you can use following advices:
+ *
+ *
Check each Tiles separatly. Try to access nested Tiles directly to test
+ * if thes work properly.
+ *
Enable Tiles logging. See the commons-logging package help.
+ *
+ */
+package org.apache.struts.tiles2;
\ No newline at end of file
diff --git a/tiles2/src/main/java/org/apache/struts/tiles2/package.html b/tiles2/src/main/java/org/apache/struts/tiles2/package.html
new file mode 100644
index 000000000..8a42a470e
--- /dev/null
+++ b/tiles2/src/main/java/org/apache/struts/tiles2/package.html
@@ -0,0 +1,341 @@
+
+
+
+Tiles Package
+
+
+
+ The Tiles taglib and framework allows building web pages by assembling reusable
+ pieces of pages, called Tiles. A Tiles is usually a simple JSP page.
+
+
+
+
Introduction
+
The Tiles framework allows building pages by assembling reusable Tiles.
+ As an example, the page in the next figure can be build by assembling a
+ header, a footer, a menu and a body.
+
+
Each Tiles (header, menu, body, ...) is a JSP page and can itself be build
+ by assembling other Tiles.
+
Using Tiles can be compared as using Java methods: You need to define the Tiles (the method body), and then you can "call" this body anywhere you want, passing it some parameters. In Tiles, parameters are called "attributes" in order to avoid confusion with the request parameters.
+
The Tiles body can be a simple JSP page, a Struts action or any URI pointing
+ to a resource inside the current web site.
+
Inserting the body, or calling it, is done with the tag <tiles:insert
+ ...> anywhere in a JSP page. Insertion can also be done by specifying
+ a definition name as the path of a Struts forward or as input,
+ forward or include attributes of a Struts action.
+
Tiles bodies are used to create layouts, reusable parts, ... Tiles insertions
+ are used to insert Tiles. The same Tiles can be reused several times in
+ the same site, or even in the same page.
+
Insertion of a Tiles body can be associated to a logical name in what Tiles calls a "definition". A definition contains a logical name, a page used as body and some attribute values. The definition declaration doesn't insert the associated Tiles body. It just associates it with the name. A definition name can be used anywhere insertion of a Tiles body can occur. The associated Tiles body is then inserted with associated attributes.
+
The definition declarations can be done in JSP pages or in one or more
+ centralized files. A definition can extend another one, overload some attributes,
+ add new attributes ... This allows the declaration of a "master" definition
+ declaring the common layout, header, menu and footer. All other definitions
+ extend this master layout thereby making it possible to change the entire
+ site look & feel simply by changing the master definition.
This example inserts the specified page, passing it the attributes. Attributes
+ are stored in a Tiles context which is passed to the inserted pag and
+ can then be accesssed by their names.
+
+
+
Retrieve an attribute value as String
+
+<tiles:getAsString name="title" />
+
+
This example retrieves the value of the attribute "title" and prints it as a String in the current output stream. The method toString() is applied on the attribute value, allowing to pass any kind of object as value.
+
+
+
Insert Tiles referenced by an attribute
+
+<tiles:insert attribute='menu' />
+
+
This inserts the Tiles referenced by the attribute "menu" value. The
+ specified attribute value is first retrieved from current Tiles's context,
+ and then the value is used as a page target to insert.
+
+
+
Classic Layout
+
This example is a layout assembling a page in the classic header-footer-menu-body
+ fashion.
The layout is declared in a JSP page (ex: /layouts/classicLayout.jsp).
+ It can be used in conjunction with the tag described in "Insert
+ a page passing some attributes".
+
+
+
+
Definitions
+
A definition associates a logical name with the URL of a Tiles to be inserted
+ and some attribute values. A definition doesn't insert the Tiles. This is
+ done later using the definition name. A definition name can be inserted
+ as often as you want in your site, making it easy to reuse a Tiles.
+
A definition can extend another definition and overload some attributes
+ or add new ones. This makes easy factorization of definitions differing
+ by some attributes. For example, you can define a master definition declaring
+ the main header, menu, footer, and a default title. Then let each of your
+ page definitions extend this master definition and overload the title and
+ the body.
+
Definitions can be declared in a JSP page, or in one or more centralized
+ files. To enable the definitions from centralized files, you need to initialize
+ the "definitions factory&" which will parse the definitions from the files
+ and provide them to the Tiles framework.
+
+
Enabling Definition Factory
+
To enable Tiles definitions described in one or more files, you need to write these files and to initialize the definition factory.
+
Initialization is different depending on the Struts version you use,
+ or if you do not use Struts at all.
+
+
Struts1.1
+
Use the Tiles plug-in to enable Tiles definitions. This plug-in creates
+ the definition factory and passese it a configuration object populated
+ with parameters. Parameters can be specified in the web.xml file or
+ as plug-in parameters. The plug-in first reads parameters from web.xml,
+ and then overloads them with the ones found in the plug-in. All parameters
+ are optional and can be omitted. The plug-in should be declared in each
+ struts-config file:
Specify configuration file names. There can be several comma separated file names (default: ?? )
+
+
+
definitions-parser-validate: (optional)
+
+
Specify if XML parser should validate the Tiles configuration
+ file
+
+
true : validate. DTD should be specified in file header (default)
+
false : no validation
+
+
+
+
+
+
+
moduleAware: (optional)
+
+
Specify if the Tiles definition factory is module aware. If true (default),
+ there will be one factory for each Struts module.
+ If false, there will be one common factory for all module. In this later case,
+ it is still needed to declare one plugin per module. The factory will be
+ initialized with parameters found in the first initialized plugin (generally the
+ one associated with the default module).
+
+
true : Tiles framework is module aware
+
false :Tiles framework has one single factoy shared among modules (default)
+
+
+
+
+
+
tilesUtilImplClassname: (optional - for advanced user)
+
+
Specify The classname of the TilesUtil implementation to use. The specified class should
+ be a subclass of TilesUtilStrutsImpl. This option disable the moduleAware option.
+ Specifying &"TilesUtilStrutsImpl&" is equivalent to moduleAware = false.
+ Specifying &"TilesUtilStrutsModuleImpl&" is equivalent to moduleAware = true.
+ This option is taken into account only once, when it is first encountered. To avoid problems,
+ it is advice to specify the same values in all TilesPlugin declaration.
+
+
+
+
+
+
The TilesPlugin class creates one definition factory for each struts module.
+
+
+ If the flag moduleAware is false, only one shared factory is created for all modules.
+ In this later case, the factory is initialized with parameters found in the first plugin.
+ The plugins should be declared in all modules, and the moduleAware flag should be
+ the same for the entire application.
+
+ Paths found in Tiles definitions are relative to the main context.
+
You don't need to specify a TilesRequestProcessor, this is automatically
+ done by the plug-in. If, however, you want to specify your own RequestProcessor,
+ it should extend the TilesRequestProcessor. The plug-in checks this
+ constraint.
+
+
+
Struts1.0.x
+
You need to use a special servlet extending the Struts servlet. This is specified in the web.xml file of your application:
+
+ <servlet>
+ <servlet-name>action</servlet-name>
+ <servlet-class>org.apache.struts.tiles.ActionComponentServlet</servlet-class>
+ <!-- Tiles Servlet parameter
+ Specify configuration file names. There can be several comma
+ separated file names
+ -->
+ <init-param>
+ <param-name>definitions-config</param-name>
+ <param-value>/WEB-INF/tiles-defs.xml</param-value>
+ </init-param>
+ <!-- Tiles Servlet parameter
+ Specify if XML parser should validate the Tiles configuration file(s).
+ true : validate. DTD should be specified in file header.
+ false : no validation
+ -->
+ <init-param>
+ <param-name>definitions-parser-validate</param-name>
+ <param-value>true</param-value>
+ </init-param>
+ ...
+ </servlet>
+
+
+
+
Without Struts
+
Tiles can be used without Struts. To initialize the definition factory, you can use the provided servlet. Declare it in the web.xml file of your application:
+<!DOCTYPE tiles-definitions PUBLIC
+ &"-//Apache Software Foundation//DTD Tiles Configuration//EN&"
+ &"http://struts.apache.org/dtds/tiles-config_1_1.dtd&">
+
+<!-- Definitions for Tiles documentation -->
+<tiles-definitions>
+
+ <!-- ========================================================== -->
+ <!-- Master definition -->
+ <!-- ========================================================== -->
+ <!-- Main page layout used as a root for other page definitions -->
+
+ <definition name=&"site.mainLayout&" path=&"/layouts/classicLayout.jsp&">
+ <put name=&"title&" value=&"Tiles Blank Site&" />
+ <put name=&"header&" value=&"/tiles/common/header.jsp&" />
+ <put name=&"menu&" value=&"site.menu.bar&" />
+ <put name=&"footer&" value=&"/tiles/common/footer.jsp&" />
+ <put name=&"body&" value=&"/tiles/body.jsp&" />
+ </definition>
+
+ <!-- ========================================================== -->
+ <!-- Index page definition -->
+ <!-- ========================================================== -->
+ <!-- This definition inherits from the main definition.
+ It overloads the page title and the body used.
+ Use the same mechanism to define new pages sharing common
+ properties (here header, menu, footer, layout)
+ -->
+
+ <definition name=&"site.index.page&" extends=&"site.mainLayout&" >
+ <put name=&"title&" value=&"Tiles Blank Site Index&" />
+ <put name=&"body&" value=&"/tiles/body.jsp&" />
+ </definition>
+
+</tiles-definition>
+
+
+
+
Debugging
+
To debug a page made of Tiles, you can use following advices:
+
+
Check each Tiles separatly. Try to access nested Tiles directly to test
+ if thes work properly.
+
Enable Tiles logging. See the commons-logging package help.
+
+
+
+
+
+
diff --git a/tiles2/src/main/java/org/apache/struts/tiles2/preparer/ActionPreparer.java b/tiles2/src/main/java/org/apache/struts/tiles2/preparer/ActionPreparer.java
new file mode 100644
index 000000000..58fe88c5a
--- /dev/null
+++ b/tiles2/src/main/java/org/apache/struts/tiles2/preparer/ActionPreparer.java
@@ -0,0 +1,68 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.struts.tiles2.preparer;
+
+import org.apache.struts.action.Action;
+import org.apache.tiles.AttributeContext;
+import org.apache.tiles.context.TilesRequestContext;
+import org.apache.tiles.preparer.PreparerException;
+import org.apache.tiles.preparer.ViewPreparerSupport;
+import org.apache.tiles.servlet.context.ServletTilesRequestContext;
+
+/**
+ * Struts wrapper implementation of Controller. This implementation wraps an
+ * Action in a Controller.
+ */
+public class ActionPreparer extends ViewPreparerSupport {
+
+ /**
+ * Struts action wrapped.
+ */
+ private Action action = null;
+
+ /**
+ * Constructor.
+ *
+ * @param action Action to be wrapped.
+ */
+ public ActionPreparer(Action action) {
+ this.action = action;
+ }
+
+ /** {@inheritDoc} */
+ public void execute(TilesRequestContext tilesContext,
+ AttributeContext attributeContext) throws PreparerException {
+ if (tilesContext instanceof ServletTilesRequestContext) {
+ ServletTilesRequestContext servletTilesContext =
+ (ServletTilesRequestContext) tilesContext;
+ try {
+ this.action.execute(null, null, servletTilesContext.getRequest(),
+ servletTilesContext.getResponse());
+ } catch (Exception e) {
+ throw new PreparerException(
+ "The enclosed action threw an exception", e);
+ }
+ } else {
+ throw new PreparerException("Not using a ServletTilesRequestContext");
+ }
+ }
+}
diff --git a/tiles2/src/main/java/org/apache/struts/tiles2/preparer/StrutsPreparerFactory.java b/tiles2/src/main/java/org/apache/struts/tiles2/preparer/StrutsPreparerFactory.java
new file mode 100644
index 000000000..c73782ad0
--- /dev/null
+++ b/tiles2/src/main/java/org/apache/struts/tiles2/preparer/StrutsPreparerFactory.java
@@ -0,0 +1,55 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.struts.tiles2.preparer;
+
+import org.apache.struts.action.Action;
+import org.apache.tiles.TilesException;
+import org.apache.tiles.preparer.BasicPreparerFactory;
+import org.apache.tiles.preparer.ViewPreparer;
+import org.apache.tiles.util.ClassUtil;
+
+/**
+ * Factory used to instantiate preparers in a Struts 1 / Tiles 2 environment.
+ *
+ * @version $Rev$ $Date$
+ */
+public class StrutsPreparerFactory extends BasicPreparerFactory {
+
+ /** {@inheritDoc} */
+ protected ViewPreparer createPreparer(String name) throws TilesException {
+ ViewPreparer retValue;
+
+ if (name.startsWith("/")) {
+ retValue = new UrlPreparer(name);
+ } else {
+ Object instance = ClassUtil.instantiate(name, true);
+ if (instance instanceof Action) {
+ retValue = new ActionPreparer((Action) instance);
+ } else {
+ retValue = super.createPreparer(name);
+ }
+ }
+
+ return retValue;
+ }
+
+}
diff --git a/tiles2/src/main/java/org/apache/struts/tiles2/preparer/UrlPreparer.java b/tiles2/src/main/java/org/apache/struts/tiles2/preparer/UrlPreparer.java
new file mode 100644
index 000000000..62d77f068
--- /dev/null
+++ b/tiles2/src/main/java/org/apache/struts/tiles2/preparer/UrlPreparer.java
@@ -0,0 +1,87 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.struts.tiles2.preparer;
+
+import java.io.IOException;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.tiles.AttributeContext;
+import org.apache.tiles.context.TilesRequestContext;
+import org.apache.tiles.preparer.PreparerException;
+import org.apache.tiles.preparer.ViewPreparer;
+import org.apache.tiles.servlet.context.ServletTilesRequestContext;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class UrlPreparer implements ViewPreparer {
+
+ /**
+ * The URL to be used as a preparer.
+ */
+ private String url;
+
+ /**
+ * Constructor.
+ *
+ * @param url The URL to be used as a preparer.
+ */
+ public UrlPreparer(String url) {
+ this.url = url;
+ }
+
+ /** {@inheritDoc} */
+ public void execute(TilesRequestContext tilesContext,
+ AttributeContext attributeContext) throws PreparerException {
+
+ if (tilesContext instanceof ServletTilesRequestContext) {
+ ServletTilesRequestContext servletTilesContext =
+ (ServletTilesRequestContext) tilesContext;
+ HttpServletRequest request = servletTilesContext.getRequest();
+ HttpServletResponse response = servletTilesContext.getResponse();
+ RequestDispatcher rd = request.getSession().getServletContext()
+ .getRequestDispatcher(url);
+ if (rd == null) {
+ throw new PreparerException(
+ "Controller can't find url '" + url + "'.");
+ }
+
+ try {
+ rd.include(request, response);
+ } catch (ServletException e) {
+ throw new PreparerException(
+ "The request dispatcher threw an exception", e);
+ } catch (IOException e) {
+ throw new PreparerException(
+ "The request dispatcher threw an I/O exception", e);
+ }
+ } else {
+ throw new PreparerException("Cannot dispatch url '" + url
+ + "' since this preparer has not been called under a servlet environment");
+ }
+ }
+
+}
diff --git a/tiles2/src/main/java/org/apache/struts/tiles2/util/PlugInConfigContextAdapter.java b/tiles2/src/main/java/org/apache/struts/tiles2/util/PlugInConfigContextAdapter.java
new file mode 100644
index 000000000..7bd27277d
--- /dev/null
+++ b/tiles2/src/main/java/org/apache/struts/tiles2/util/PlugInConfigContextAdapter.java
@@ -0,0 +1,393 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.struts.tiles2.util;
+
+import org.apache.struts.config.PlugInConfig;
+import org.apache.tiles.servlet.context.ServletTilesApplicationContext;
+
+import javax.servlet.*;
+import javax.servlet.descriptor.JspConfigDescriptor;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.*;
+
+/**
+ * Adapts a {@link PlugInConfig} object to become a ServletContext object,
+ * exposing init parameters methods.
+ */
+public class PlugInConfigContextAdapter extends ServletTilesApplicationContext implements ServletContext {
+
+ /**
+ * The internal plugin config object.
+ */
+ private final PlugInConfig plugInConfigObject;
+
+ /**
+ * The Map of context initialization parameters.
+ */
+ private final Map initParam;
+
+ /**
+ * Constructor.
+ *
+ * @param plugInConfigObject The plugin config object to use.
+ * @param servletContext The servlet context to use.
+ */
+ public PlugInConfigContextAdapter(PlugInConfig plugInConfigObject,
+ ServletContext servletContext) {
+ super(servletContext);
+ this.plugInConfigObject = plugInConfigObject;
+
+ HashMap initParam_ = new HashMap<>(super.getInitParams());
+ for (Map.Entry entry : plugInConfigObject.getProperties().entrySet()) {
+ initParam_.put(entry.getKey(), entry.getValue().toString());
+ }
+ initParam = Collections.unmodifiableMap(initParam_);
+ }
+
+ @Override
+ public Map getInitParams() {
+ return initParam;
+ }
+
+ /**
+ * Returns the internal plugin config object.
+ *
+ * @return the internal plugin config object
+ */
+ public PlugInConfig getPlugInConfigObject() {
+ return plugInConfigObject;
+ }
+
+ @Override
+ public String getContextPath() {
+ return getServletContext().getContextPath();
+ }
+
+ @Override
+ public ServletContext getContext(String uripath) {
+ return getServletContext().getContext(uripath);
+ }
+
+ @Override
+ public int getMajorVersion() {
+ return getServletContext().getMajorVersion();
+ }
+
+ @Override
+ public int getMinorVersion() {
+ return getServletContext().getMinorVersion();
+ }
+
+ @Override
+ public int getEffectiveMajorVersion() {
+ return getServletContext().getEffectiveMajorVersion();
+ }
+
+ @Override
+ public int getEffectiveMinorVersion() {
+ return getServletContext().getEffectiveMinorVersion();
+ }
+
+ @Override
+ public String getMimeType(String file) {
+ return getServletContext().getMimeType(file);
+ }
+
+ @Override
+ public Set getResourcePaths(String path) {
+ return getServletContext().getResourcePaths(path);
+ }
+
+ @Override
+ public InputStream getResourceAsStream(String path) {
+ return getServletContext().getResourceAsStream(path);
+ }
+
+ @Override
+ public RequestDispatcher getRequestDispatcher(String path) {
+ return getServletContext().getRequestDispatcher(path);
+ }
+
+ @Override
+ public RequestDispatcher getNamedDispatcher(String name) {
+ return getServletContext().getNamedDispatcher(name);
+ }
+
+ @Override
+ public Servlet getServlet(String name) throws ServletException {
+ return getServletContext().getServlet(name);
+ }
+
+ @Override
+ public Enumeration getServlets() {
+ return getServletContext().getServlets();
+ }
+
+ @Override
+ public Enumeration getServletNames() {
+ return getServletContext().getServletNames();
+ }
+
+ @Override
+ public void log(String msg) {
+ getServletContext().log(msg);
+ }
+
+ @Override
+ public void log(Exception exception, String msg) {
+ getServletContext().log(exception, msg);
+ }
+
+ @Override
+ public void log(String message, Throwable throwable) {
+ getServletContext().log(message, throwable);
+ }
+
+ @Override
+ public String getRealPath(String path) {
+ return getServletContext().getRealPath(path);
+ }
+
+ @Override
+ public String getServerInfo() {
+ return getServletContext().getServerInfo();
+ }
+
+ /**
+ * Returns an initialization parameter.
+ *
+ * @param parameterName The name of the parameter.
+ * @return The value of the parameter.
+ */
+ public String getInitParameter(String parameterName) {
+ String retValue;
+
+ retValue = (String) plugInConfigObject.getProperties()
+ .get(parameterName);
+ if (retValue == null) {
+ retValue = getServletContext().getInitParameter(parameterName);
+ }
+
+ return retValue;
+ }
+
+ /**
+ * Returns the names of all initialization parameters.
+ *
+ * @return The names of all initialization parameters.
+ */
+ public Enumeration getInitParameterNames() {
+ return getServletContext().getInitParameterNames();
+ }
+
+ @Override
+ public boolean setInitParameter(String name, String value) {
+ return getServletContext().setInitParameter(name, value);
+ }
+
+ @Override
+ public Object getAttribute(String name) {
+ return getServletContext().getAttribute(name);
+ }
+
+ @Override
+ public Enumeration getAttributeNames() {
+ return getServletContext().getAttributeNames();
+ }
+
+ @Override
+ public void setAttribute(String name, Object object) {
+ getServletContext().setAttribute(name, object);
+ }
+
+ @Override
+ public void removeAttribute(String name) {
+ getServletContext().removeAttribute(name);
+ }
+
+ @Override
+ public String getServletContextName() {
+ return getServletContext().getServletContextName();
+ }
+
+ @Override
+ public ServletRegistration.Dynamic addServlet(String servletName, String className) {
+ return getServletContext().addServlet(servletName, className);
+ }
+
+ @Override
+ public ServletRegistration.Dynamic addServlet(String servletName, Servlet servlet) {
+ return getServletContext().addServlet(servletName, servlet);
+ }
+
+ @Override
+ public ServletRegistration.Dynamic addServlet(String servletName, Class extends Servlet> servletClass) {
+ return getServletContext().addServlet(servletName, servletClass);
+ }
+
+ @Override
+ public ServletRegistration.Dynamic addJspFile(String servletName, String jspFile) {
+ return getServletContext().addJspFile(servletName, jspFile);
+ }
+
+ @Override
+ public T createServlet(Class clazz) throws ServletException {
+ return getServletContext().createServlet(clazz);
+ }
+
+ @Override
+ public ServletRegistration getServletRegistration(String servletName) {
+ return getServletContext().getServletRegistration(servletName);
+ }
+
+ @Override
+ public Map getServletRegistrations() {
+ return getServletContext().getServletRegistrations();
+ }
+
+ @Override
+ public FilterRegistration.Dynamic addFilter(String filterName, String className) {
+ return getServletContext().addFilter(filterName, className);
+ }
+
+ @Override
+ public FilterRegistration.Dynamic addFilter(String filterName, Filter filter) {
+ return getServletContext().addFilter(filterName, filter);
+ }
+
+ @Override
+ public FilterRegistration.Dynamic addFilter(String filterName, Class extends Filter> filterClass) {
+ return getServletContext().addFilter(filterName, filterClass);
+ }
+
+ @Override
+ public T createFilter(Class clazz) throws ServletException {
+ return getServletContext().createFilter(clazz);
+ }
+
+ @Override
+ public FilterRegistration getFilterRegistration(String filterName) {
+ return getServletContext().getFilterRegistration(filterName);
+ }
+
+ @Override
+ public Map getFilterRegistrations() {
+ return getServletContext().getFilterRegistrations();
+ }
+
+ @Override
+ public SessionCookieConfig getSessionCookieConfig() {
+ return getServletContext().getSessionCookieConfig();
+ }
+
+ @Override
+ public void setSessionTrackingModes(Set sessionTrackingModes) {
+ getServletContext().setSessionTrackingModes(sessionTrackingModes);
+ }
+
+ @Override
+ public Set getDefaultSessionTrackingModes() {
+ return getServletContext().getDefaultSessionTrackingModes();
+ }
+
+ @Override
+ public Set getEffectiveSessionTrackingModes() {
+ return getServletContext().getEffectiveSessionTrackingModes();
+ }
+
+ @Override
+ public void addListener(String className) {
+ getServletContext().addListener(className);
+ }
+
+ @Override
+ public void addListener(T t) {
+ getServletContext().addListener(t);
+ }
+
+ @Override
+ public void addListener(Class extends EventListener> listenerClass) {
+ getServletContext().addListener(listenerClass);
+ }
+
+ @Override
+ public T createListener(Class clazz) throws ServletException {
+ return getServletContext().createListener(clazz);
+ }
+
+ @Override
+ public JspConfigDescriptor getJspConfigDescriptor() {
+ return getServletContext().getJspConfigDescriptor();
+ }
+
+ @Override
+ public ClassLoader getClassLoader() {
+ return getServletContext().getClassLoader();
+ }
+
+ @Override
+ public void declareRoles(String... roleNames) {
+ getServletContext().declareRoles(roleNames);
+ }
+
+ @Override
+ public String getVirtualServerName() {
+ return getServletContext().getVirtualServerName();
+ }
+
+ @Override
+ public int getSessionTimeout() {
+ return getServletContext().getSessionTimeout();
+ }
+
+ @Override
+ public void setSessionTimeout(int sessionTimeout) {
+ getServletContext().setSessionTimeout(sessionTimeout);
+ }
+
+ @Override
+ public String getRequestCharacterEncoding() {
+ return getServletContext().getRequestCharacterEncoding();
+ }
+
+ @Override
+ public void setRequestCharacterEncoding(String encoding) {
+ getServletContext().setRequestCharacterEncoding(encoding);
+ }
+
+ @Override
+ public String getResponseCharacterEncoding() {
+ return getServletContext().getResponseCharacterEncoding();
+ }
+
+ @Override
+ public void setResponseCharacterEncoding(String encoding) {
+ getServletContext().setResponseCharacterEncoding(encoding);
+ }
+
+ @Override
+ public URL getResource(String path) throws MalformedURLException {
+ return getServletContext().getResource(path);
+ }
+}
\ No newline at end of file
diff --git a/tiles2/src/main/resources/LICENSE.txt b/tiles2/src/main/resources/LICENSE.txt
new file mode 100644
index 000000000..dd5b3a58a
--- /dev/null
+++ b/tiles2/src/main/resources/LICENSE.txt
@@ -0,0 +1,174 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
diff --git a/tiles2/src/main/resources/NOTICE.txt b/tiles2/src/main/resources/NOTICE.txt
new file mode 100644
index 000000000..db75b1f6c
--- /dev/null
+++ b/tiles2/src/main/resources/NOTICE.txt
@@ -0,0 +1,10 @@
+Apache Struts Tiles
+Copyright 2000-2007 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+
+This product includes the ANTLR parsing library,
+developed by JGuru.com (http://www.antlr.org and
+http://www.jguru.com).
+
diff --git a/tiles2/src/main/resources/org/apache/struts/tiles2/chain-config.xml b/tiles2/src/main/resources/org/apache/struts/tiles2/chain-config.xml
new file mode 100644
index 000000000..a4b23c4ef
--- /dev/null
+++ b/tiles2/src/main/resources/org/apache/struts/tiles2/chain-config.xml
@@ -0,0 +1,256 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tiles2/src/site/fml/faq.fml b/tiles2/src/site/fml/faq.fml
new file mode 100644
index 000000000..45bac7599
--- /dev/null
+++ b/tiles2/src/site/fml/faq.fml
@@ -0,0 +1,43 @@
+
+
+
+
+
+ Can I use Tiles without Struts?
+
+
+ Yes. Stand-alone Tiles is currently in the Struts Sandbox, and
+ nightly builds are available
+ here.
+
+
+
+
+ Why are there two versions?
+
+
+ Stand-alone Tiles is still under development. Until it emerges
+ from the Sandbox, the Struts Action Framework will continue to depend
+ on Struts Tiles.
+
The following examples illustrate Tiles' templating features using a
+ basic template. The template contains three elements: a title, a header,
+ and a body displayed vertically. These elements will be manipulated in
+ various ways in each example. Tiles' flexibility will be demonstrated by
+ defining the template "inline" in a JSP page and by loading it from a
+ "factory" defined in an XML file.
+
+
+
+
The first example shows the basic template. There are three ways to
+ define the template. First, it can be defined anonymously in a JSP page
+ by using the Tiles insert tag. Secondly, it can be defined in a JSP
+ using the Tiles definition tag. Finally, it can be defined in an XML
+ file and loaded from a factory using the Tiles insert tag. This example
+ will illustrate all three methods. First, let's look at the output of
+ the example. Then we will examine each method.
+
+ Example Output
+
+
+
+
This is the title.
+
+
+
This is the header
+
+
+
+
+
This is the body
+
+
+
+
+
+
First let's look at the template. The layout.jsp file contains the
+ template code. This file does not change no matter whether the Tile
+ is defined anonymously, in a JSP, or in an XML definitions file.
+
+ file: layout.jsp
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ]]>
+
+
Next we show the template being inserted anonymously using the Tiles
+ insert tag. The insert tag is used to define the Tile and insert it in
+ a single action. The Tile is not placed in the Definitions Factory and
+ is not available for later use. The template is invoked and the
+ attributes are filled in. Notice that the title is inserted directly and
+ the header and body values are included JSP pages.
+
+ file: somepage.jsp
+
+
+
+
+
+
+
+ ]]>
+
+ file: header.jsp
+ This is the header
+
+ ]]>
+
+ file: body.jsp
+ This is a body
+ ]]>
+
+
Now we will see the same example in a different way. In this version the
+ Tile is defined in a JSP using the Tiles definition tag. This works very
+ similarly to the anonymous version. The only difference is that it is not
+ anonymous. Using this method the template is included and populated and
+ the Tile is inserted into the Definitions Factory so that it can be used
+ by other JSP pages.
+
+ file: somepage.jsp
+
+
+
+
+
+
+
+
+ ]]>
+
+
Using this method of defining Tiles can be very tricky. If you define a
+ Tile like this and then insert it in another page using the Tiles insert
+ tag, you must make sure that JSP page will never be invoked before the
+ page that defines the Tile. The Tiles Definitions Factory is stored in
+ application scope. So if the server is restarted or the Definitions
+ Factory is reloaded for any reason, a Tile defined in a JSP page is not
+ reloaded until that JSP page is invoked.
+
+
The scenario above can be avoided by defining Tiles in an XML configuration
+ file. The file is loaded at servlet startup using the Tiles Servlet or
+ a plugin. The example below defines the Tile in an XML file and
+ uses the Tiles insert tag in a JSP to invoke it.
This is the preferred method of defining Tiles. It ensures that all
+ definitions are loaded at application startup and reduces the coupling
+ between JSP pages.
+
+
+
+
+
+
The previous examples used the put tag to set
+ attributes in a Tiles definition. In those examples Tiles inferred they
+ attribute type. In most cases this is fine as long as you understand the
+ rules of how value types are inferred. More on that later. This example
+ shows that you can specify the attribute type to give Tiles a hint about
+ what to do with the value.
The above code is really no different from the first example. Tiles
+ would've inferred the types we specified. There are several valid
+ settings for the type attribute. However, they all resolve to just
+ three different types. The type will be interpreted in one of the
+ following ways.
+
+
+
String. Value will be inserted directly in the
+ page as text.
+
Definition. Value points to a valid Tiles definition
+ that will be processed and inserted in the page.
+
Page. Value points to a JSP page that will be
+ included in the current page.
+
+
+
In most cases Tiles will determine the appropriate type. When would you
+ need to specify it? Perhaps you have an attribute that is a logo that is
+ either reused or overriden for a Tile. Tiles might interpret this value
+ as a path and try to process it as a JSP page. If you specify it as a
+ String it will be inserted directly into the page. It would also be
+ useful to specify the type if the value points to a Tiles definition
+ and you want to make sure Tiles doesn't interpret it as a direct
+ String.
+
+
+
+
+
+ Example Output
+
+
+
+
Test with tag body.
+
+
+
+ This header is inserted as body of tag
+
+
+
+
This is the body
+
+
+
+
+
+ file: WEB-INF/tiles-defs.xml
+
+
+
+ This header is inserted as body of tag
+
+
+
+...
+ ]]>
+
+
+
+
+
+
+
+
diff --git a/tiles2/src/site/xdoc/index.xml b/tiles2/src/site/xdoc/index.xml
new file mode 100644
index 000000000..c17bc52f4
--- /dev/null
+++ b/tiles2/src/site/xdoc/index.xml
@@ -0,0 +1,166 @@
+
+
+
+
+
+ Welcome
+
+
+
+
+
+
+ Welcome to the Struts Tiles component.Tiles is a templating
+ system. (Include on steriods.) It can be used to create a common look
+ and feel for a web application. Tiles can also be used to create
+ reusable view components. This site will help
+ you get started with Tiles.
+
+
+ Tiles can also be used without Struts. A new release of Tiles,
+ Tiles 2, is being prepared. If you would like to use Tiles without
+ Struts, see the new Tiles 2 subproject.
+ The focus of this site is using Tiles with Struts.
+
+
+
+
+
+
Screen definitions
+
+
Create a screen by assembling
+ Tiles : header, footer,
+ menu, body, etc.
+
+
+ Definitions can take place :
+
+
in a centralized XML file
+
directly in JSP pages
+
programatically in Actions
+
+
+
+ Definitions provide an inheritance
+ mechanism : a definition can extend another one,
+ and override parameters.
+
+
+
+
+ Layouts
+
+
+ Define common page layouts and reuse
+ them across your website.
+
+
+ Define menu layouts, and use them by
+ passing lists of items and links.
+
+
+ Define a portal layout, use it by
+ passing a list of Tiles
+ (pages) to show.
+
+
+ Reuse existing layouts, or define
+ your own.
+
+
+
+
+ Dynamic page building
+
+
+ Tiles can be gathered dynamically during
+ page reload. It is possible to change any attribute:
+ layout, list of Tiles in portal, list of menu
+ items, etc.
+
+
+
+
+ Reuse of Tiles /
+ Components
+
+
+ If well defined, a
+ Tile can be reused across multiple
+ applications.
+
+
+ Dynamic attributes are used to
+ parameterize Tiles.
+
+
+ It is possible to define a library of
+ reusable Tiles.
+
+
+ Build a page by assembling predefined
+ components, giving them appropriate parameters.
+
+
+
+
+ Internationalization (i18n)
+
+
+
+ It is possible to load different tiles
+ according to Locale.
+
+
+ A mechanism similar to Java properties
+ files is used for definitions files: you can have one
+ definition file per Locale. The appropriate definition is
+ loaded according to the current Locale.
+
+
+
+ Multi-channels
+
+
+
+ It is possible to load different Tiles
+ according to a key.
+
+
+
+ For example, the key could represent user privileges,
+ browser type, arbitrary name stored in session, etc.
+
+
+
+ A mechanism similar to Java properties
+ files is used for definitions files: you can have one
+ definition file per key. The appropriate definition is
+ loaded according to the key.
+
+ Configure the Tiles Plugin to load your definitions.
+
+
+
+ ]]>
+
+
+ At the top of each JSP page that will use the Tiles custom tags,
+ add a line that declares the Tiles custom tag library.
+
+
+ ]]>
+
+
+
+
+
+
+
WARNING - Do NOT add
+ tiles.jar to the classpath of your servlet container in
+ an attempt to avoid placing it in the /WEB-INF/lib
+ directory of each individual web app! Doing so will cause problems with
+ ClassNotFoundException exceptions.
+
+
For most containers, you need only to:
+
+
Copy the WAR files in your Tiles /webapp directory
+ to your containers webapps directory.
+
In some cases, you may need to restart your container if it
+ is running.
The XML example above is representative of real-life usage. But it does
+ not illustrate every aspect of the Tiles configuration file. We will
+ now examine each portion of the configuration file in detail.
+
+
+
+
+
A definition can define a template or a "tile." If it is defining
+ a template its path will point to a JSP page that contains the layout
+ of the template. The definition's attributes will point to various
+ sections of the template that can be either used as is or overriden.
+
+
If a definition defines a tile it may refer to a named portion of a
+ page such as the header, or it may refer to a reusable component, such
+ as a customer form.
+
+
A template definition would be similar to the mainLayout
+ definition above. It defines a template containing a layout and 5 named
+ attributes. The "title" attribute is a String attribute that can be
+ overridden. The "header" and "footer" attributes are pages that are
+ included in the template. The "menu" and "body" attributes are
+ definitions that would be defined elsewhere in the file.
+
+
A tile definition would be similar to the mainMenu
+ definition above. This configures a menu tile that can be included
+ anywhere on a page.
+
+
The following list shows the attributes of the Definition tag.
+
+
+
controllerClass
+ The fully qualified Java class name of the controller
+ subclass to call immediately before the tiles is inserted.
+ Only one of controllerClass or controllerUrl should be
+ specified.
+
+
controllerUrl
+ The context-relative path to the resource used as controller
+ called immediately before the tiles is inserted.
+ Only one of controllerClass or controllerUrl should be
+ specified.
+
+
extends
+ Name of a definition that is used as ancestor of this definition.
+ All attributes from the ancestor are available to the new
+ definition. Any attribute inherited from the ancestor can
+ be overloaded by providing a new value.
+
+
name (Required).
+ The unique identifier for this definition.
+
+
page
+ Same as path.
+
+
path
+ The context-relative path to the resource used as tiles to
+ insert. This tiles will be inserted and a tiles context
+ containing appropriate attributes will be available.
+
+
role
+ Security role name that is allowed access to this definition
+ object. The definition is inserted only if the role name is
+ allowed.
+
+
template
+ Same as path. For compatibility with the template tag library.
+
+
+
+
+
The "put" element describes an attribute of a definition. Definition
+ attributes have a name and a value. The value can be specified as an
+ xml attribute, or in the body of the <put>tag.
+
+
A definition attribute can be one of three basic types. It can be
+ a String value that is inserted into a page. This value can be a
+ simple String specified in the "value" attribute of the "put" tag or
+ it can be complex HTML content specified as the body of the "put" tag.
+ The attribute can also be the URL of a page to be included in another
+ page. Thirdly, it can be the name of another Tiles definition to
+ be inserted in a page.
+
+
The following list shows the attributes of the Put tag.
+
+
+
content
+ Same as value.
+
+
direct
+ Same as type="string".
+
+
name (Required)
+ The unique identifier for this put.
+
+
type
+ The type of the value. Can be: string, page, template or
+ definition. By default, no type is associated to a value. If a
+ type is associated, it will be used as a hint to process the
+ value when the attribute will be used in the inserted tiles. A
+ type of "string" indicates that the value should be inserted
+ directly into the content of the page. A type of "page" or
+ "template" indicates that the value is the URL of a page that
+ should be included. A type of "definition" indicates that the
+ value is the name of another Tiles definition that should be
+ included in the page.
+
+
value
+ The value associated to this tiles attribute. The "value"
+ attribute is required if the value is not specified in the
+ content of the "put" tag.
+
+
+
+
+
+
+
The PutList tag is similar to the Put tag except that it allows you
+ to specify a list of attributes for a Tiles Definition. It specifies
+ an attribute that is a Java List containing any kind of values. In
+ the config file, the list elements are specified by nested
+ add, item or
+ putList elements.
+
+
The following list shows the attributes of the PutList tag.
+
+
+
name (Required).
+ The unique identifier for this put list.
+
+
+
+
+
The add element describes an element of a list. It
+ is similar to the put element except that it is only
+ used in lists. It supports the following attributes.
+
+
+
content
+ Same as value.
+
+
direct
+ Same as type="string".
+
+
name (Required)
+ The unique identifier for this put.
+
+
type
+ The type of the value. Can be: string, page, template or
+ definition. By default, no type is associated to a value. If a
+ type is associated, it will be used as a hint to process the
+ value when the attribute will be used in the inserted tiles. A
+ type of "string" indicates that the value should be inserted
+ directly into the content of the page. A type of "page" or
+ "template" indicates that the value is the URL of a page that
+ should be included. A type of "definition" indicates that the
+ value is the name of another Tiles definition that should be
+ included in the page.
+
+
value
+ The value associated to this tiles attribute. The "value"
+ attribute is required if the value is not specified in the
+ content of the "add" tag.
+
+
+
+
+
+
+
The bean element describes an element of a list. It
+ causes a bean of the specified java classtype to be created. This
+ bean is initialized with appropriate nested
+ set-property elements.
+
+
+
classtype (Required).
+ The fully qualified classname for this bean.
+
+
+
+
+
The set-property element specifies the method name
+ and initial value of a bean property. When the object representing
+ the surrounding element is instantiated, the accessor for the
+ indicated property is called and passed the indicated value.
+
+
+
property (Required).
+ Name of the JavaBeans property whose setter method will be
+ called.
+
+
value (Required).
+ String representation of the value to which this property will
+ be set, after suitable type conversion
+
+
+
+
+
+
The item element describes an element of a list.
+ It causes a bean of the specified classtype to be created and added
+ to the list. Each bean can contain different properties: value, link,
+ icon, tooltip. These properties are to be interpreted by the jsp
+ page using them.
+
+
Using the Item element is a good way to build menus. By default the
+ bean is of type
+ org.apache.struts.tiles.beans.SimpleMenuItem. The
+ following attributes are supported.
+
+
+
classtype
+ The fully qualified classtype for this bean. If specified, the
+ classtype must be a subclass of the interface
+ org.apache.struts.tiles.beans.MenuItem.
+
+
icon
+ Link to the icon for the menu item.
+
+
link (Required).
+ URL of the location pointed to by the menu item.
+
+
tooltip
+ Alternative text describing the menu item.
+
+
value (Required)
+ The String to be displayed on the menu.
+
+
+
+
+
The description element contains descriptive
+ (paragraph length) text about the surrounding element, suitable for
+ use in GUI tools.
+
+
+
+
The display-name element contains a short (one line)
+ description of the surrounding element, suitable for use in GUI
+ tools.
+
+
+
+
The icon element contains a small-icon and
+ large-icon element which specify the location, relative to the
+ Tiles configuration file, for small and large images used to
+ represent the surrounding element in GUI tools.
+
+
+
+
The large-icon element specifies the location,
+ relative to the Struts configuration file, of a resource containing
+ a large (32x32 pixel) icon image.
+
+
+
+
The large-icon element specifies the location,
+ relative to the Struts configuration file, of a resource containing
+ a large (16x16 pixel) icon image.
+
+
+
+
+
+
+
+
+Tiles has been covered by many books and articles.
+
To initialize the {@code TilesDefinitionFactory}, use
* {@code org.apache.struts.chain.commands.legacy.TilesPlugin}. This class is a
- * simple extension to {@code org.apache.struts.tiles2.TilesPlugin} which
+ * simple extension to {@code org.apache.struts.tiles3.TilesPlugin} which
* simply does not interfere with your choice of {@code RequestProcessor}
* implementation.