Merge pull request #920 from apache/fix/WW-5419-tiles
[WW-5419] Fixes support for loading Tiles definitions
diff --git a/plugins/tiles/pom.xml b/plugins/tiles/pom.xml
index 208e50f..845062b 100644
--- a/plugins/tiles/pom.xml
+++ b/plugins/tiles/pom.xml
@@ -102,6 +102,16 @@
<artifactId>log4j-jcl</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-test</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
diff --git a/plugins/tiles/src/main/java/org/apache/struts2/tiles/StrutsTilesContainerFactory.java b/plugins/tiles/src/main/java/org/apache/struts2/tiles/StrutsTilesContainerFactory.java
index ed03f82..4cda085 100644
--- a/plugins/tiles/src/main/java/org/apache/struts2/tiles/StrutsTilesContainerFactory.java
+++ b/plugins/tiles/src/main/java/org/apache/struts2/tiles/StrutsTilesContainerFactory.java
@@ -68,10 +68,7 @@
import javax.el.ResourceBundleELResolver;
import javax.servlet.jsp.JspFactory;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -105,19 +102,16 @@
/**
* Default pattern to be used to collect Tiles definitions if user didn't configure any
+ */
+ public static final Set<String> TILES_DEFAULT_PATTERNS = TextParseUtil.commaDelimitedStringToSet("*tiles*.xml");
+
+ /**
+ * Default pattern to be used to collect Tiles definitions if user didn't configure any
*
* @deprecated since Struts 6.4.0, use {@link #TILES_DEFAULT_PATTERNS} instead
*/
@Deprecated
- public static final String TILES_DEFAULT_PATTERN = "/WEB-INF/**/tiles*.xml,classpath*:META-INF/**/tiles*.xml";
-
- /**
- * Default pattern to be used to collect Tiles definitions if user didn't configure any
- */
- public static final Set<String> TILES_DEFAULT_PATTERNS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
- "/WEB-INF/**/tiles*.xml",
- "classpath*:META-INF/**/tiles*.xml"
- )));
+ public static final String TILES_DEFAULT_PATTERN = String.join(",", TILES_DEFAULT_PATTERNS);
/**
* Supported expression languages
diff --git a/plugins/tiles/src/main/java/org/apache/struts2/tiles/StrutsWildcardServletApplicationContext.java b/plugins/tiles/src/main/java/org/apache/struts2/tiles/StrutsWildcardServletApplicationContext.java
index 7af6069..2a30eb6 100644
--- a/plugins/tiles/src/main/java/org/apache/struts2/tiles/StrutsWildcardServletApplicationContext.java
+++ b/plugins/tiles/src/main/java/org/apache/struts2/tiles/StrutsWildcardServletApplicationContext.java
@@ -43,7 +43,7 @@
private static final Logger LOG = LogManager.getLogger(StrutsWildcardServletApplicationContext.class);
- private ResourceFinder finder;
+ private final ResourceFinder finder;
public StrutsWildcardServletApplicationContext(ServletContext context) {
super(context);
@@ -64,16 +64,15 @@
}
try {
- Enumeration<URL> resources = getClass().getClassLoader().getResources("/");
+ Enumeration<URL> resources = getClass().getClassLoader().getResources("");
while (resources.hasMoreElements()) {
- URL resource = resources.nextElement();
- urls.add(resource);
+ urls.add(resources.nextElement());
}
} catch (IOException e) {
throw new ConfigurationException(e);
}
- finder = new ResourceFinder(urls.toArray(new URL[urls.size()]));
+ finder = new ResourceFinder(urls.toArray(new URL[0]));
}
public Collection<ApplicationResource> getResources(String path) {
diff --git a/plugins/tiles/src/test/java/org/apache/struts2/tiles/StrutsTilesContainerFactoryTest.java b/plugins/tiles/src/test/java/org/apache/struts2/tiles/StrutsTilesContainerFactoryTest.java
index 122bfe5..944aac2 100644
--- a/plugins/tiles/src/test/java/org/apache/struts2/tiles/StrutsTilesContainerFactoryTest.java
+++ b/plugins/tiles/src/test/java/org/apache/struts2/tiles/StrutsTilesContainerFactoryTest.java
@@ -34,8 +34,8 @@
import org.junit.Before;
import org.junit.Test;
-import javax.servlet.ServletContext;
import javax.servlet.jsp.JspFactory;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@@ -64,12 +64,11 @@
Objects.requireNonNull(getClass().getResource("/org/apache/tiles/core/config/tiles-defs.xml"))
);
ApplicationResource classpathResource = new URLApplicationResource(
- "/org/apache/tiles/core/config/defs1.xml",
- Objects.requireNonNull(getClass().getResource("/org/apache/tiles/core/config/defs1.xml"))
+ "/org/apache/tiles/core/config/tiles_defs1.xml",
+ Objects.requireNonNull(getClass().getResource("/org/apache/tiles/core/config/tiles_defs1.xml"))
);
when(applicationContext.getInitParams()).thenReturn(Collections.emptyMap());
- when(applicationContext.getResources("/WEB-INF/**/tiles*.xml")).thenReturn(Collections.singleton(pathResource));
- when(applicationContext.getResources("classpath*:META-INF/**/tiles*.xml")).thenReturn(Collections.singleton(classpathResource));
+ when(applicationContext.getResources("*tiles*.xml")).thenReturn(Arrays.asList(pathResource, classpathResource));
List<ApplicationResource> resources = factory.getSources(applicationContext);
assertEquals("The urls list is not two-sized", 2, resources.size());
diff --git a/plugins/tiles/src/test/java/org/apache/struts2/tiles/StrutsWildcardServletApplicationContextTest.java b/plugins/tiles/src/test/java/org/apache/struts2/tiles/StrutsWildcardServletApplicationContextTest.java
new file mode 100644
index 0000000..972ed70
--- /dev/null
+++ b/plugins/tiles/src/test/java/org/apache/struts2/tiles/StrutsWildcardServletApplicationContextTest.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2.tiles;
+
+import org.apache.tiles.core.definition.DefinitionsFactory;
+import org.apache.tiles.request.ApplicationResource;
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.core.io.FileSystemResource;
+import org.springframework.core.io.FileUrlResource;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+import org.springframework.mock.web.MockServletContext;
+
+import javax.servlet.ServletContext;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Collection;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class StrutsWildcardServletApplicationContextTest {
+
+ private ServletContext context;
+
+ @Before
+ public void setUp() throws Exception {
+ URL resource = getClass().getResource("/");
+ context = new MockServletContext(resource.getPath(), new ResourceLoader() {
+ @Override
+ public Resource getResource(String location) {
+ try {
+ String finalLocation = location.replaceAll("//", "/");
+ if (finalLocation.endsWith("/")) {
+ return new FileSystemResource(finalLocation);
+ }
+ return new FileUrlResource(finalLocation);
+ } catch (MalformedURLException e) {
+ return null;
+ }
+ }
+
+ @Override
+ public ClassLoader getClassLoader() {
+ return StrutsWildcardServletApplicationContextTest.class.getClassLoader();
+ }
+ });
+ }
+
+ @Test
+ public void wildcardSupport() {
+ StrutsWildcardServletApplicationContext applicationContext = new StrutsWildcardServletApplicationContext(context);
+
+ Collection<ApplicationResource> resources = applicationContext.getResources("*tiles*.xml");
+
+ assertThat(resources)
+ .hasSize(1)
+ .extracting(ApplicationResource::getLocalePath)
+ .first().asString()
+ .endsWith("/WEB-INF/tiles.xml");
+ }
+
+}
\ No newline at end of file
diff --git a/plugins/tiles/src/test/resources/WEB-INF/tiles.xml b/plugins/tiles/src/test/resources/WEB-INF/tiles.xml
new file mode 100644
index 0000000..9fc36a4
--- /dev/null
+++ b/plugins/tiles/src/test/resources/WEB-INF/tiles.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+-->
+
+<!DOCTYPE tiles-definitions PUBLIC
+ "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
+ "http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
+
+<tiles-definitions>
+
+ <!-- Doc index page description -->
+ <definition name="top.mainLayout" template="/layout/classicLayout.jsp">
+ <put-attribute name="title" value="Tiles Library Documentation"/>
+ <put-attribute name="header" value="/common/header.jsp"/>
+ <put-attribute name="menu" value="doc.menu.main"/>
+ <put-attribute name="footer" value="/common/footer.jsp"/>
+ <put-attribute name="body" value="doc.portal.body"/>
+ <put-attribute name="bean" value="This is an object" type="object"/>
+ </definition>
+
+</tiles-definitions>
diff --git a/plugins/tiles/src/test/resources/org/apache/tiles/core/config/tiles_defs1.xml b/plugins/tiles/src/test/resources/org/apache/tiles/core/config/tiles_defs1.xml
new file mode 100644
index 0000000..621d7ce
--- /dev/null
+++ b/plugins/tiles/src/test/resources/org/apache/tiles/core/config/tiles_defs1.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+ "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
+ "http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
+
+<!-- Definitions for Tiles documentation -->
+
+<tiles-definitions>
+
+ <!-- ======================================================= -->
+ <!-- Master definition -->
+ <!-- ======================================================= -->
+
+ <!-- This definition will remain the same for all locales -->
+ <definition name="test.common" template="/test.jsp">
+ <put-attribute name="country" value="none"/>
+ <put-attribute name="title" value="Common Definition" />
+ <put-attribute name="header" value="/common/header.jsp" />
+ <put-attribute name="menu" value="doc.menu.main" />
+ <put-attribute name="footer" value="/common/footer.jsp" />
+ <put-attribute name="body" value="doc.portal.body" />
+ </definition>
+
+ <!-- Doc index page description -->
+ <definition name="test.def1" template="/test.jsp">
+ <put-attribute name="country" value="default"/>
+ <put-attribute name="title" value="Tiles Library Documentation" />
+ <put-attribute name="header" value="/common/header.jsp" />
+ <put-attribute name="menu" value="doc.menu.main" />
+ <put-attribute name="footer" value="/common/footer.jsp" />
+ <put-attribute name="body" value="doc.portal.body" />
+ </definition>
+
+ <!-- This definition will be extended -->
+ <definition name="test.def.toextend" template="/test.jsp">
+ <put-attribute name="country" value="default"/>
+ <put-attribute name="title" value="Definition to be extended" />
+ <put-attribute name="header" value="/common/header.jsp" />
+ <put-attribute name="menu" value="doc.menu.main" />
+ <put-attribute name="footer" value="/common/footer.jsp" />
+ <put-attribute name="body" value="doc.portal.body" />
+ </definition>
+
+ <!-- This definition will be overridden -->
+ <definition name="test.def.overridden" template="/test.jsp">
+ <put-attribute name="country" value="default"/>
+ <put-attribute name="title" value="Definition to be overridden" />
+ <put-attribute name="header" value="/common/header.jsp" />
+ <put-attribute name="menu" value="doc.menu.main" />
+ <put-attribute name="footer" value="/common/footer.jsp" />
+ <put-attribute name="body" value="doc.portal.body" />
+ </definition>
+
+</tiles-definitions>