WW-4594 Merges #85 which adds annotations to configure tiles

This commit is contained in:
cnenning
2016-02-03 10:51:15 +01:00
16 changed files with 760 additions and 13 deletions
@@ -0,0 +1,40 @@
/*
* 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.showcase.tiles;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.tiles.annotation.TilesDefinition;
import org.apache.struts2.tiles.annotation.TilesPutAttribute;
import com.opensymphony.xwork2.ActionSupport;
@Namespace("/tiles")
@ParentPackage("tiles")
@Result(name = "success", type="tiles")
@TilesDefinition(extend = "showcase.annotations", putAttributes = {
@TilesPutAttribute(name = "header", value = "/WEB-INF/tiles/header.jsp"),
@TilesPutAttribute(name = "body", value = "/WEB-INF/tiles/body.ftl")
})
public class TilesAnnotationsAction extends ActionSupport {
private static final long serialVersionUID = 2900509995064928866L;
}
@@ -22,8 +22,8 @@
-->
<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
"http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
"-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
"http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
<tiles-definitions>
@@ -45,4 +45,10 @@
<put-attribute name="body" value="/WEB-INF/tiles/body.ftl"/>
</definition>
<definition name="showcase.annotations" template="/WEB-INF/tiles/layout-annotations.jsp">
<put-attribute name="title" value="Tiles Annotations Showcase"/>
<put-attribute name="header" value=".header"/>
<put-attribute name="body" value=".body"/>
</definition>
</tiles-definitions>
@@ -16,6 +16,9 @@
<li>
<a href="freemarkerLayout.action">View Example with a FreeMarker Layout</a>
</li>
<li>
<a href="tiles-annotations.action">View Example with tiles configuration by annotating action</a>
</li>
</ul>
</div>
@@ -0,0 +1,14 @@
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%-- Show usage; Used in Header --%>
<tiles:importAttribute name="title" scope="request"/>
<html>
<head><title>Struts2 Showcase - <tiles:getAsString name="title"/></title></head>
<body>
<tiles:insertAttribute name="header"/>
<tiles:insertAttribute name="body"/>
<p>Notice that this is a layout made in JSP</p>
<p>It is configured with <strong>annotations!</strong></p>
</body>
</html>
@@ -0,0 +1,177 @@
/*
* 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.commons.lang3.StringUtils;
import org.apache.struts2.tiles.annotation.TilesAddAttribute;
import org.apache.struts2.tiles.annotation.TilesAddListAttribute;
import org.apache.struts2.tiles.annotation.TilesDefinition;
import org.apache.struts2.tiles.annotation.TilesDefinitions;
import org.apache.struts2.tiles.annotation.TilesPutAttribute;
import org.apache.struts2.tiles.annotation.TilesPutListAttribute;
import org.apache.tiles.Attribute;
import org.apache.tiles.Definition;
import org.apache.tiles.Expression;
import org.apache.tiles.ListAttribute;
/**
* Processes tiles annotations to create {@link Definition}s and
* {@link Attribute}s in a way as close to <code>tiles.xml</code> as possible.
*
*/
public class StrutsTilesAnnotationProcessor {
/**
* Search strategy is as follows:
* <ul>
* <li>Check if action has Annotation {@link TilesDefinition}</li>
* <li>If not, check if action has Annotation {@link TilesDefinitions}</li>
* <li>If given tileName is not null and present in {@link TilesDefinitions}, return it</li>
* <li>Return first element of {@link TilesDefinitions}</li>
* <li>Return null</li>
* </ul>
*
* @param action
* Annotated action.
* @param tileName
* Tilename to search for. May be null in some circumstances.
* @return {@link TilesDefinition}
*/
public TilesDefinition findAnnotation(Object action, String tileName) {
Class<? extends Object> clazz = action.getClass();
TilesDefinition tilesDefinition = clazz.getAnnotation(TilesDefinition.class);
TilesDefinitions tilesDefinitions = clazz.getAnnotation(TilesDefinitions.class);
if (tilesDefinition == null && tilesDefinitions != null) {
if (!StringUtils.isEmpty(tileName)) {
for (TilesDefinition i : tilesDefinitions.value()) {
if (i.name() != null && i.name().equals(tileName)) {
tilesDefinition = i;
break;
}
}
} else {
if (tilesDefinitions.value().length > 0) {
tilesDefinition = tilesDefinitions.value()[0];
}
}
}
return tilesDefinition;
}
/**
* Builds a {@link Definition} based on given {@link TilesDefinition} with
* given name.
*
* @param tileName
* name for resulting {@link Definition}.
* @param tilesDefinition
* {@link TilesDefinition} to process.
* @return {@link Definition} represented by given {@link TilesDefinition}.
*/
public Definition buildTilesDefinition(String tileName, TilesDefinition tilesDefinition) {
Definition definition = new Definition();
definition.setName(tileName);
String extend = getValueOrNull(tilesDefinition.extend());
if (extend != null) {
definition.setExtends(extend);
}
String preparer = getValueOrNull(tilesDefinition.preparer());
if (preparer != null) {
definition.setPreparer(preparer);
}
definition.setTemplateAttribute(buildTemplateAttribute(tilesDefinition));
for (TilesPutAttribute putAttribute : tilesDefinition.putAttributes()) {
Attribute attribute = buildPutAttribute(putAttribute);
definition.putAttribute(putAttribute.name(), attribute, putAttribute.cascade());
}
for (TilesPutListAttribute putListAttribute : tilesDefinition.putListAttributes()) {
Attribute attribute = buildPutListAttribute(putListAttribute);
definition.putAttribute(putListAttribute.name(), attribute, putListAttribute.cascade());
}
return definition;
}
protected Attribute buildTemplateAttribute(TilesDefinition tilesDef) {
// see tiles DigesterDefinitionsReader
Attribute attribute = Attribute.createTemplateAttribute(getValueOrNull(tilesDef.template()));
String templateExpression = getValueOrNull(tilesDef.templateExpression());
Expression expression = Expression.createExpressionFromDescribedExpression(templateExpression);
attribute.setExpressionObject(expression);
attribute.setRole(getValueOrNull(tilesDef.role()));
String templateType = getValueOrNull(tilesDef.templateType());
if (templateType != null) {
attribute.setRenderer(templateType);
} else if (getValueOrNull(tilesDef.extend()) != null && templateType == null) {
attribute.setRenderer(null);
}
return attribute;
}
protected Attribute buildPutAttribute(TilesPutAttribute putAttribute) {
Attribute attribute = new Attribute();
attribute.setValue(getValueOrNull(putAttribute.value()));
String expression = getValueOrNull(putAttribute.expression());
attribute.setExpressionObject(Expression.createExpressionFromDescribedExpression(expression));
attribute.setRole(getValueOrNull(putAttribute.role()));
attribute.setRenderer(getValueOrNull(putAttribute.type()));
return attribute;
}
protected Attribute buildPutListAttribute(TilesPutListAttribute putListAttribute) {
ListAttribute attribute = new ListAttribute();
attribute.setRole(getValueOrNull(putListAttribute.role()));
attribute.setInherit(putListAttribute.inherit());
for (TilesAddAttribute addAttribute : putListAttribute.addAttributes()) {
attribute.add(buildAddAttribute(addAttribute));
}
for (TilesAddListAttribute addListAttribute : putListAttribute.addListAttributes()) {
attribute.add(buildAddListAttribute(addListAttribute));
}
return attribute;
}
protected Attribute buildAddAttribute(TilesAddAttribute addAttribute) {
Attribute attribute = new Attribute();
attribute.setValue(getValueOrNull(addAttribute.value()));
String expression = getValueOrNull(addAttribute.expression());
attribute.setExpressionObject(Expression.createExpressionFromDescribedExpression(expression));
attribute.setRole(getValueOrNull(addAttribute.role()));
attribute.setRenderer(getValueOrNull(addAttribute.type()));
return attribute;
}
protected Attribute buildAddListAttribute(TilesAddListAttribute addListAttribute) {
ListAttribute attribute = new ListAttribute();
attribute.setRole(getValueOrNull(addListAttribute.role()));
for (TilesAddAttribute addAttribute : addListAttribute.addAttributes()) {
attribute.add(buildAddAttribute(addAttribute));
}
return attribute;
}
protected String getValueOrNull(String value) {
return value != null && value.length() > 0 ? value : null;
}
}
@@ -0,0 +1,30 @@
/*
* 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.annotation;
/**
* Represents a <code>&lt;add-attribute&gt;</code> element in <code>tiles.xml</code>.
*
*/
public @interface TilesAddAttribute {
String expression() default "";
String role() default "";
String type() default "";
String value() default "";
}
@@ -0,0 +1,28 @@
/*
* 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.annotation;
/**
* Represents a <code>&lt;add-list-attribute&gt;</code> element in <code>tiles.xml</code>.
*
*/
public @interface TilesAddListAttribute {
String role() default "";
TilesAddAttribute[] addAttributes() default {};
}
@@ -0,0 +1,66 @@
/*
* 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.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Represents a <code>&lt;definition&gt;</code> element in <code>tiles.xml</code>.
*
* <p>
* With a sample layout in <code>tiles.xml</code> like this:
* <pre>
* &lt;definition name="layout" template="/WEB-INF/tiles/layout.jsp"&gt;
* &lt;put-attribute name="header" value=".header"/&gt;
* &lt;put-attribute name="body" value=".body"/&gt;
* &lt;/definition&gt;
* </pre>
* </p>
* <p>
* You can annotate an action like that:
* <pre>
* @Result(name = "success", type="tiles")
* @TilesDefinition(extend = "layout", putAttributes = {
* @TilesPutAttribute(name = "header", value = "/WEB-INF/tiles/header.jsp"),
* @TilesPutAttribute(name = "body", value = "/WEB-INF/tiles/body.ftl")
* })
* public class FooAction extends ActionSupport {
* </pre>
* </p>
*
*/
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = { ElementType.TYPE })
@Inherited
public @interface TilesDefinition {
String extend() default "";
String name() default "";
String preparer() default "";
String role() default "";
String template() default "";
String templateExpression() default "";
String templateType() default "";
TilesPutAttribute[] putAttributes() default {};
TilesPutListAttribute[] putListAttributes() default {};
}
@@ -0,0 +1,36 @@
/*
* 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.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* An array of {@link TilesDefinition}s.
*
*/
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = { ElementType.TYPE })
@Inherited
public @interface TilesDefinitions {
TilesDefinition[] value();
}
@@ -0,0 +1,32 @@
/*
* 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.annotation;
/**
* Represents a <code>&lt;put-attribute&gt;</code> element in <code>tiles.xml</code>.
*
*/
public @interface TilesPutAttribute {
boolean cascade() default false;
String expression() default "";
String name() default "";
String role() default "";
String type() default "";
String value() default "";
}
@@ -0,0 +1,32 @@
/*
* 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.annotation;
/**
* Represents a <code>&lt;put-list-attribute&gt;</code> element in <code>tiles.xml</code>.
*
*/
public @interface TilesPutListAttribute {
boolean cascade() default false;
boolean inherit() default false;
String name() default "";
String role() default "";
TilesAddAttribute[] addAttributes() default {};
TilesAddListAttribute[] addListAttributes() default {};
}
@@ -25,12 +25,20 @@ import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.result.ServletDispatcherResult;
import org.apache.struts2.tiles.StrutsTilesAnnotationProcessor;
import org.apache.struts2.tiles.annotation.TilesDefinition;
import org.apache.tiles.Definition;
import org.apache.tiles.TilesContainer;
import org.apache.tiles.TilesException;
import com.opensymphony.xwork2.ActionInvocation;
import org.apache.tiles.access.TilesAccess;
import org.apache.tiles.mgmt.MutableTilesContainer;
import org.apache.tiles.request.ApplicationContext;
import org.apache.tiles.request.Request;
import org.apache.tiles.request.servlet.ServletRequest;
@@ -42,18 +50,11 @@ import org.apache.tiles.request.servlet.ServletUtil;
* <!-- END SNIPPET: description -->
*
* <!-- START SNIPPET: webxml -->
* In your web.xml file, you need to add a servlet entry for TilesServlet to load the tiles
* definitions into the ServletContext.
* In your web.xml file, you need to add a TilesListener.
*
* &lt;servlet&gt;
* &lt;servlet-name&gt;tiles&lt;/servlet-name&gt;
* &lt;servlet-class&gt;org.apache.tiles.servlets.TilesServlet&lt;/servlet-class&gt;
* &lt;init-param&gt;
* &lt;param-name&gt;definitions-config&lt;/param-name&gt;
* &lt;param-value&gt;/WEB-INF/tiles-config.xml&lt;/param-value&gt;
* &lt;/init-param&gt;
* &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
* &lt;/servlet&gt;
* &lt;listener&gt;
* &lt;listener-class&gt;org.apache.struts2.tiles.StrutsTilesListener&lt;/listener-class&gt;
* &lt;/listener&gt;
* <!-- END SNIPPET: webxml -->
*
* <!-- START SNIPPET: strutsxml -->
@@ -76,11 +77,20 @@ import org.apache.tiles.request.servlet.ServletUtil;
* &lt;/result-types&gt;
* <!-- END SNIPPET: packageconfig -->
*
*
* <!-- START SNIPPET: tilesconfig -->
* You have to configure tiles itself. Therefore you can add <code>tiles.xml</code> either
* to resources or WEB-INF. You may also use annotations like {@link TilesDefinition}.
*
* <!-- END SNIPPET: tilesconfig -->
*
*/
public class TilesResult extends ServletDispatcherResult {
private static final long serialVersionUID = -3806939435493086244L;
private static final Logger LOG = LogManager.getLogger(TilesResult.class);
public TilesResult() {
super();
}
@@ -99,6 +109,18 @@ public class TilesResult extends ServletDispatcherResult {
* HTTP request.
*/
public void doExecute(String location, ActionInvocation invocation) throws Exception {
StrutsTilesAnnotationProcessor annotationProcessor = new StrutsTilesAnnotationProcessor();
TilesDefinition tilesDefinition = null;
Object action = invocation.getAction();
String actionName = invocation.getInvocationContext().getName();
if (StringUtils.isEmpty(location)) {
LOG.trace("location not set -> action must have one @TilesDefinition");
tilesDefinition = annotationProcessor.findAnnotation(action, null);
String tileName = StringUtils.isNotEmpty(tilesDefinition.name()) ? tilesDefinition.name() : actionName;
location = tileName;
LOG.debug("using new location name '{}' and @TilesDefinition '{}'", location, tilesDefinition);
}
setLocation(location);
ServletContext servletContext = ServletActionContext.getServletContext();
@@ -111,6 +133,31 @@ public class TilesResult extends ServletDispatcherResult {
Request request = new ServletRequest(applicationContext, httpRequest, httpResponse);
boolean definitionValid = false;
try {
LOG.debug("checking if tiles definition exists '{}'", location);
definitionValid = container.isValidDefinition(location, request);
} catch (TilesException e) {
LOG.warn("got TilesException while checking if definiton exists, ignoring it", e);
}
if (!definitionValid) {
if (tilesDefinition == null) {
LOG.trace("tilesDefinition not found yet, searching in action");
tilesDefinition = annotationProcessor.findAnnotation(action, location);
}
if (tilesDefinition != null) {
Definition definition = annotationProcessor.buildTilesDefinition(location, tilesDefinition);
if (container instanceof MutableTilesContainer) {
LOG.debug("registering tiles definition with name '{}'", definition.getName());
((MutableTilesContainer)container).register(definition, request);
} else {
LOG.error("cannot register tiles definition as tiles container is not mutable!");
}
} else {
LOG.warn("could not find @TilesDefinition for action: {}", actionName);
}
}
container.render(location, request);
}
}
@@ -0,0 +1,147 @@
package org.apache.struts2.tiles;
import java.util.List;
import java.util.Set;
import org.apache.struts2.tiles.annotation.TilesDefinition;
import org.apache.tiles.Attribute;
import org.apache.tiles.Definition;
import org.apache.tiles.Expression;
import org.junit.Test;
import org.junit.Assert;
public class StrutsTilesAnnotationProcessorTest {
@Test
public void findAnnotationSingleAction() {
StrutsTilesAnnotationProcessor annotationProcessor = new StrutsTilesAnnotationProcessor();
TilesDefinition tilesDefinition = annotationProcessor.findAnnotation(new TilesTestActionSingleAnnotation(), null);
Assert.assertNotNull(tilesDefinition);
Assert.assertEquals("definition-name", tilesDefinition.name());
}
@Test
public void findAnnotationMultipleActionNameNull() {
StrutsTilesAnnotationProcessor annotationProcessor = new StrutsTilesAnnotationProcessor();
TilesDefinition tilesDefinition = annotationProcessor.findAnnotation(new TilesTestActionMultipleAnnotations(), null);
Assert.assertNotNull(tilesDefinition);
Assert.assertEquals("def1", tilesDefinition.name());
}
@Test
public void findAnnotationMultipleActionNameGiven() {
StrutsTilesAnnotationProcessor annotationProcessor = new StrutsTilesAnnotationProcessor();
TilesDefinition tilesDefinition = annotationProcessor.findAnnotation(new TilesTestActionMultipleAnnotations(), "def2");
Assert.assertNotNull(tilesDefinition);
Assert.assertEquals("def2", tilesDefinition.name());
}
@Test
public void findAnnotationMultipleActionNotFound() {
StrutsTilesAnnotationProcessor annotationProcessor = new StrutsTilesAnnotationProcessor();
TilesDefinition tilesDefinition = annotationProcessor.findAnnotation(new TilesTestActionMultipleAnnotations(), "def3");
Assert.assertNull(tilesDefinition);
}
@Test
public void buildDefiniton() {
StrutsTilesAnnotationProcessor annotationProcessor = new StrutsTilesAnnotationProcessor();
TilesDefinition tilesDefinition = annotationProcessor.findAnnotation(new TilesTestActionSingleAnnotation(), null);
Definition definition = annotationProcessor.buildTilesDefinition("tileName", tilesDefinition);
Assert.assertNotNull(definition);
Assert.assertEquals("tileName", definition.getName());
Assert.assertEquals("preparer", definition.getPreparer());
Assert.assertEquals("base-definition", definition.getExtends());
Attribute templateAttribute = definition.getTemplateAttribute();
Assert.assertEquals("template", templateAttribute.getValue());
Assert.assertEquals("type", templateAttribute.getRenderer());
Assert.assertEquals("role", templateAttribute.getRole());
Expression definitionExpressionObject = templateAttribute.getExpressionObject();
Assert.assertEquals("templ*", definitionExpressionObject.getExpression());
Assert.assertNull(definitionExpressionObject.getLanguage());
Attribute putAttribute = definition.getAttribute("put-attr");
Assert.assertNotNull(putAttribute);
Assert.assertEquals("attr-val", putAttribute.getValue());
Assert.assertEquals("attr-type", putAttribute.getRenderer());
Assert.assertEquals("attr-role", putAttribute.getRole());
Expression putAttrExpressionObject = putAttribute.getExpressionObject();
Assert.assertEquals("expr", putAttrExpressionObject.getExpression());
Assert.assertEquals("lang", putAttrExpressionObject.getLanguage());
Attribute listAttribute = definition.getAttribute("list-name");
Assert.assertEquals("list-role", listAttribute.getRole());
List<Attribute> listValue = getListValue(listAttribute);
Assert.assertEquals(2, listValue.size());
Attribute addAttribute = listValue.get(0);
Assert.assertEquals("list-attr-role", addAttribute.getRole());
Assert.assertEquals("list-attr-val", addAttribute.getValue());
Assert.assertEquals("list-attr-type", addAttribute.getRenderer());
Expression addAttrExpressionObject = addAttribute.getExpressionObject();
Assert.assertEquals("list-attr-expr", addAttrExpressionObject.getExpression());
Attribute addListAttribute = listValue.get(1);
Assert.assertEquals("list-list-attr-role", addListAttribute.getRole());
List<Attribute> addListValue = getListValue(addListAttribute);
Assert.assertEquals(1, addListValue.size());
Assert.assertEquals("list-list-add-attr", addListValue.get(0).getValue());
Set<String> cascadedAttributeNames = definition.getCascadedAttributeNames();
Assert.assertEquals(2, cascadedAttributeNames.size());
Assert.assertTrue(cascadedAttributeNames.contains("put-attr"));
Assert.assertTrue(cascadedAttributeNames.contains("list-name"));
}
@Test
public void buildDefinitonAllEmpty() {
StrutsTilesAnnotationProcessor annotationProcessor = new StrutsTilesAnnotationProcessor();
TilesDefinition tilesDefinition = annotationProcessor.findAnnotation(new TilesTestActionSingleAnnotationAllEmpty(), null);
Definition definition = annotationProcessor.buildTilesDefinition(null, tilesDefinition);
Assert.assertNotNull(definition);
Assert.assertNull(definition.getName());
Assert.assertNull(definition.getPreparer());
Assert.assertNull(definition.getExtends());
Attribute templateAttribute = definition.getTemplateAttribute();
Assert.assertNull(templateAttribute.getValue());
Assert.assertNull(templateAttribute.getRole());
Assert.assertNull(templateAttribute.getExpressionObject());
Attribute putAttribute = definition.getAttribute("put-attr");
Assert.assertNotNull(putAttribute);
Assert.assertNull(putAttribute.getValue());
Assert.assertNull(putAttribute.getRenderer());
Assert.assertNull(putAttribute.getRole());
Assert.assertNull(putAttribute.getExpressionObject());
Attribute listAttribute = definition.getAttribute("list-name");
Assert.assertNull(listAttribute.getRole());
List<Attribute> listValue = getListValue(listAttribute);
Assert.assertEquals(2, listValue.size());
Attribute addAttribute = listValue.get(0);
Assert.assertNull(addAttribute.getRole());
Assert.assertNull(addAttribute.getValue());
Assert.assertNull(addAttribute.getRenderer());
Assert.assertNull(addAttribute.getExpressionObject());
Attribute addListAttribute = listValue.get(1);
Assert.assertNull(addListAttribute.getRole());
List<Attribute> addListValue = getListValue(addListAttribute);
Assert.assertEquals(1, addListValue.size());
Assert.assertNull(addListValue.get(0).getValue());
Set<String> cascadedAttributeNames = definition.getCascadedAttributeNames();
Assert.assertNull(cascadedAttributeNames);
}
@SuppressWarnings("unchecked")
protected List<Attribute> getListValue(Attribute listAttribute) {
return (List<Attribute>) listAttribute.getValue();
}
}
@@ -0,0 +1,12 @@
package org.apache.struts2.tiles;
import org.apache.struts2.tiles.annotation.TilesDefinition;
import org.apache.struts2.tiles.annotation.TilesDefinitions;
@TilesDefinitions({
@TilesDefinition(name="def1"),
@TilesDefinition(name="def2"),
})
public class TilesTestActionMultipleAnnotations {
}
@@ -0,0 +1,49 @@
package org.apache.struts2.tiles;
import org.apache.struts2.tiles.annotation.TilesAddAttribute;
import org.apache.struts2.tiles.annotation.TilesAddListAttribute;
import org.apache.struts2.tiles.annotation.TilesDefinition;
import org.apache.struts2.tiles.annotation.TilesPutAttribute;
import org.apache.struts2.tiles.annotation.TilesPutListAttribute;
@TilesDefinition(
name = "definition-name",
extend = "base-definition",
preparer = "preparer",
role = "role",
template = "template",
templateExpression = "templ*",
templateType = "type",
putAttributes = {
@TilesPutAttribute(
cascade = true,
expression = "lang:expr",
name = "put-attr",
role = "attr-role",
type = "attr-type",
value = "attr-val")
},
putListAttributes = {
@TilesPutListAttribute(
cascade = true,
inherit = true,
name = "list-name",
role = "list-role",
addAttributes = {
@TilesAddAttribute(
expression = "list-attr-expr",
role = "list-attr-role",
type = "list-attr-type",
value = "list-attr-val")
},
addListAttributes = {
@TilesAddListAttribute(
role = "list-list-attr-role",
addAttributes = {@TilesAddAttribute("list-list-add-attr")})
}
)
}
)
public class TilesTestActionSingleAnnotation {
}
@@ -0,0 +1,28 @@
package org.apache.struts2.tiles;
import org.apache.struts2.tiles.annotation.TilesAddAttribute;
import org.apache.struts2.tiles.annotation.TilesAddListAttribute;
import org.apache.struts2.tiles.annotation.TilesDefinition;
import org.apache.struts2.tiles.annotation.TilesPutAttribute;
import org.apache.struts2.tiles.annotation.TilesPutListAttribute;
@TilesDefinition(
putAttributes = {
@TilesPutAttribute(name = "put-attr")
},
putListAttributes = {
@TilesPutListAttribute(
name = "list-name",
addAttributes = {
@TilesAddAttribute()
},
addListAttributes = {
@TilesAddListAttribute(
addAttributes = {@TilesAddAttribute()})
}
)
}
)
public class TilesTestActionSingleAnnotationAllEmpty {
}