Merge pull request #920 from apache/fix/WW-5419-tiles

[WW-5419] Fixes support for loading Tiles definitions
This commit is contained in:
Lukasz Lenart
2024-05-06 18:20:54 +02:00
committed by GitHub
7 changed files with 217 additions and 22 deletions
+10
View File
@@ -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>
@@ -68,10 +68,7 @@ import javax.el.MapELResolver;
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;
@@ -103,21 +100,18 @@ public class StrutsTilesContainerFactory extends BasicTilesContainerFactory {
public static final String PATTERN_WILDCARD = "WILDCARD";
public static final String PATTERN_REGEXP = "REGEXP";
/**
* 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
@@ -43,7 +43,7 @@ public class StrutsWildcardServletApplicationContext extends ServletApplicationC
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 @@ public class StrutsWildcardServletApplicationContext extends ServletApplicationC
}
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) {
@@ -34,8 +34,8 @@ import org.apache.tiles.request.render.Renderer;
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 @@ public class StrutsTilesContainerFactoryTest {
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());
@@ -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");
}
}
@@ -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>
@@ -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>