From d9f4054b1367cd7ab6e3f22b9cc677f62def4e83 Mon Sep 17 00:00:00 2001 From: cnenning Date: Fri, 22 Jan 2016 14:59:48 +0100 Subject: [PATCH 01/11] fixed tiles showcase by setting dtd to 3.0 --- .../src/main/webapp/WEB-INF/tiles.xml | 96 +++++++++---------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/apps/showcase/src/main/webapp/WEB-INF/tiles.xml b/apps/showcase/src/main/webapp/WEB-INF/tiles.xml index 7c7057f67..027f9a459 100644 --- a/apps/showcase/src/main/webapp/WEB-INF/tiles.xml +++ b/apps/showcase/src/main/webapp/WEB-INF/tiles.xml @@ -1,48 +1,48 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + From 9ac326aa2458fe43140c1b13b61c87752d282e3d Mon Sep 17 00:00:00 2001 From: cnenning Date: Fri, 22 Jan 2016 15:27:09 +0100 Subject: [PATCH 02/11] Added tiles annotations, see WW-4594. Added tiles annotations, created StrutsTilesAnnotationProcessor to create Definitons from them and using it in TilesResult. --- .../tiles/StrutsTilesAnnotationProcessor.java | 176 +++++++++++ .../tiles/annotation/TilesAddAttribute.java | 30 ++ .../annotation/TilesAddListAttribute.java | 28 ++ .../tiles/annotation/TilesDefinition.java | 45 +++ .../tiles/annotation/TilesDefinitions.java | 36 +++ .../tiles/annotation/TilesPutAttribute.java | 32 ++ .../annotation/TilesPutListAttribute.java | 32 ++ .../struts2/views/tiles/TilesResult.java | 279 ++++++++++-------- 8 files changed, 542 insertions(+), 116 deletions(-) create mode 100644 plugins/tiles/src/main/java/org/apache/struts2/tiles/StrutsTilesAnnotationProcessor.java create mode 100644 plugins/tiles/src/main/java/org/apache/struts2/tiles/annotation/TilesAddAttribute.java create mode 100644 plugins/tiles/src/main/java/org/apache/struts2/tiles/annotation/TilesAddListAttribute.java create mode 100644 plugins/tiles/src/main/java/org/apache/struts2/tiles/annotation/TilesDefinition.java create mode 100644 plugins/tiles/src/main/java/org/apache/struts2/tiles/annotation/TilesDefinitions.java create mode 100644 plugins/tiles/src/main/java/org/apache/struts2/tiles/annotation/TilesPutAttribute.java create mode 100644 plugins/tiles/src/main/java/org/apache/struts2/tiles/annotation/TilesPutListAttribute.java diff --git a/plugins/tiles/src/main/java/org/apache/struts2/tiles/StrutsTilesAnnotationProcessor.java b/plugins/tiles/src/main/java/org/apache/struts2/tiles/StrutsTilesAnnotationProcessor.java new file mode 100644 index 000000000..2ae3ba4c9 --- /dev/null +++ b/plugins/tiles/src/main/java/org/apache/struts2/tiles/StrutsTilesAnnotationProcessor.java @@ -0,0 +1,176 @@ +/* + * 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 tiles.xml as possible. + * + */ +public class StrutsTilesAnnotationProcessor { + + /** + * Search strategy is as follows: + * + * + * @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 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; + } + } + } + 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; + } +} diff --git a/plugins/tiles/src/main/java/org/apache/struts2/tiles/annotation/TilesAddAttribute.java b/plugins/tiles/src/main/java/org/apache/struts2/tiles/annotation/TilesAddAttribute.java new file mode 100644 index 000000000..0e668de0d --- /dev/null +++ b/plugins/tiles/src/main/java/org/apache/struts2/tiles/annotation/TilesAddAttribute.java @@ -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 <add-attribute> element in tiles.xml. + * + */ +public @interface TilesAddAttribute { + String expression() default ""; + String role() default ""; + String type() default ""; + String value() default ""; +} diff --git a/plugins/tiles/src/main/java/org/apache/struts2/tiles/annotation/TilesAddListAttribute.java b/plugins/tiles/src/main/java/org/apache/struts2/tiles/annotation/TilesAddListAttribute.java new file mode 100644 index 000000000..d65066fcc --- /dev/null +++ b/plugins/tiles/src/main/java/org/apache/struts2/tiles/annotation/TilesAddListAttribute.java @@ -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 <add-list-attribute> element in tiles.xml. + * + */ +public @interface TilesAddListAttribute { + String role() default ""; + TilesAddAttribute[] addAttributes() default {}; +} diff --git a/plugins/tiles/src/main/java/org/apache/struts2/tiles/annotation/TilesDefinition.java b/plugins/tiles/src/main/java/org/apache/struts2/tiles/annotation/TilesDefinition.java new file mode 100644 index 000000000..a71bbc3be --- /dev/null +++ b/plugins/tiles/src/main/java/org/apache/struts2/tiles/annotation/TilesDefinition.java @@ -0,0 +1,45 @@ +/* + * 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 <definition> element in tiles.xml. + * + */ +@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 {}; +} diff --git a/plugins/tiles/src/main/java/org/apache/struts2/tiles/annotation/TilesDefinitions.java b/plugins/tiles/src/main/java/org/apache/struts2/tiles/annotation/TilesDefinitions.java new file mode 100644 index 000000000..fb5cc95bb --- /dev/null +++ b/plugins/tiles/src/main/java/org/apache/struts2/tiles/annotation/TilesDefinitions.java @@ -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(); +} diff --git a/plugins/tiles/src/main/java/org/apache/struts2/tiles/annotation/TilesPutAttribute.java b/plugins/tiles/src/main/java/org/apache/struts2/tiles/annotation/TilesPutAttribute.java new file mode 100644 index 000000000..c31d49ee7 --- /dev/null +++ b/plugins/tiles/src/main/java/org/apache/struts2/tiles/annotation/TilesPutAttribute.java @@ -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 <put-attribute> element in tiles.xml. + * + */ +public @interface TilesPutAttribute { + boolean cascade() default false; + String expression() default ""; + String name() default ""; + String role() default ""; + String type() default ""; + String value() default ""; +} diff --git a/plugins/tiles/src/main/java/org/apache/struts2/tiles/annotation/TilesPutListAttribute.java b/plugins/tiles/src/main/java/org/apache/struts2/tiles/annotation/TilesPutListAttribute.java new file mode 100644 index 000000000..be7a507f2 --- /dev/null +++ b/plugins/tiles/src/main/java/org/apache/struts2/tiles/annotation/TilesPutListAttribute.java @@ -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 <put-list-attribute> element in tiles.xml. + * + */ +public @interface TilesPutListAttribute { + boolean cascade() default false; + boolean inherit() default false; + String name() default ""; + String role() default ""; + TilesAddAttribute[] addAttributes() default {}; + TilesAddListAttribute[] addListAttributes() default {}; +} diff --git a/plugins/tiles/src/main/java/org/apache/struts2/views/tiles/TilesResult.java b/plugins/tiles/src/main/java/org/apache/struts2/views/tiles/TilesResult.java index a4028690a..da0076575 100644 --- a/plugins/tiles/src/main/java/org/apache/struts2/views/tiles/TilesResult.java +++ b/plugins/tiles/src/main/java/org/apache/struts2/views/tiles/TilesResult.java @@ -1,116 +1,163 @@ -/* - * $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.struts2.views.tiles; - -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.struts2.ServletActionContext; -import org.apache.struts2.result.ServletDispatcherResult; -import org.apache.tiles.TilesContainer; - -import com.opensymphony.xwork2.ActionInvocation; -import org.apache.tiles.access.TilesAccess; -import org.apache.tiles.request.ApplicationContext; -import org.apache.tiles.request.Request; -import org.apache.tiles.request.servlet.ServletRequest; -import org.apache.tiles.request.servlet.ServletUtil; - -/** - * - * Renders a view using struts-tiles. - * - * - * - * In your web.xml file, you need to add a servlet entry for TilesServlet to load the tiles - * definitions into the ServletContext. - * - * <servlet> - * <servlet-name>tiles</servlet-name> - * <servlet-class>org.apache.tiles.servlets.TilesServlet</servlet-class> - * <init-param> - * <param-name>definitions-config</param-name> - * <param-value>/WEB-INF/tiles-config.xml</param-value> - * </init-param> - * <load-on-startup>1</load-on-startup> - * </servlet> - * - * - * - * In struts.xml, use type="tiles" on your <result>. - * - * <action name="editUser" class="userAction" method="edit"> - * <result name="success" type="tiles">userForm</result> - * <result name="input" type="tiles">userList</result> - * </action> - * - * - * - * - * - * Making this result type the default for the current package. - * - * <result-types> - * <result-type name="tiles" - * class="org.apache.struts2.views.tiles.TilesResult" default="true" /> - * </result-types> - * - * - */ -public class TilesResult extends ServletDispatcherResult { - - private static final long serialVersionUID = -3806939435493086244L; - - public TilesResult() { - super(); - } - - public TilesResult(String location) { - super(location); - } - - /** - * Dispatches to the given location. Does its forward via a RequestDispatcher. If the - * dispatch fails a 404 error will be sent back in the http response. - * - * @param location the location to dispatch to. - * @param invocation the execution state of the action - * @throws Exception if an error occurs. If the dispatch fails the error will go back via the - * HTTP request. - */ - public void doExecute(String location, ActionInvocation invocation) throws Exception { - setLocation(location); - - ServletContext servletContext = ServletActionContext.getServletContext(); - - ApplicationContext applicationContext = ServletUtil.getApplicationContext(servletContext); - TilesContainer container = TilesAccess.getContainer(applicationContext); - - HttpServletRequest httpRequest = ServletActionContext.getRequest(); - HttpServletResponse httpResponse = ServletActionContext.getResponse(); - - Request request = new ServletRequest(applicationContext, httpRequest, httpResponse); - - container.render(location, request); - } -} +/* + * $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.struts2.views.tiles; + +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; +import org.apache.tiles.request.servlet.ServletUtil; + +/** + * + * Renders a view using struts-tiles. + * + * + * + * In your web.xml file, you need to add a TilesListener. + * + * <listener> + * <listener-class>org.apache.struts2.tiles.StrutsTilesListener</listener-class> + * </listener> + * + * + * + * In struts.xml, use type="tiles" on your <result>. + * + * <action name="editUser" class="userAction" method="edit"> + * <result name="success" type="tiles">userForm</result> + * <result name="input" type="tiles">userList</result> + * </action> + * + * + * + * + * + * Making this result type the default for the current package. + * + * <result-types> + * <result-type name="tiles" + * class="org.apache.struts2.views.tiles.TilesResult" default="true" /> + * </result-types> + * + * + * + * + * You have to configure tiles itself. Therefore you can add tiles.xml either + * to resources or WEB-INF. You may also use annotations like {@link TilesDefinition}. + * + * + * + */ +public class TilesResult extends ServletDispatcherResult { + + private static final long serialVersionUID = -3806939435493086244L; + + private static final Logger LOG = LogManager.getLogger(TilesResult.class); + + public TilesResult() { + super(); + } + + public TilesResult(String location) { + super(location); + } + + /** + * Dispatches to the given location. Does its forward via a RequestDispatcher. If the + * dispatch fails a 404 error will be sent back in the http response. + * + * @param location the location to dispatch to. + * @param invocation the execution state of the action + * @throws Exception if an error occurs. If the dispatch fails the error will go back via the + * 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)) { + // 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(); + + ApplicationContext applicationContext = ServletUtil.getApplicationContext(servletContext); + TilesContainer container = TilesAccess.getContainer(applicationContext); + + HttpServletRequest httpRequest = ServletActionContext.getRequest(); + HttpServletResponse httpResponse = ServletActionContext.getResponse(); + + 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) { + // tilesDefinition not found yet, search 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); + } +} From e50c37c5ba5781900edf53f9ec71b8649471d448 Mon Sep 17 00:00:00 2001 From: cnenning Date: Fri, 22 Jan 2016 15:27:50 +0100 Subject: [PATCH 03/11] added sample for tiles annotations --- .../tiles/TilesAnnotationsAction.java | 21 ++++++++ .../src/main/webapp/WEB-INF/tiles.xml | 6 +++ .../src/main/webapp/WEB-INF/tiles/body.jsp | 49 ++++++++++--------- .../WEB-INF/tiles/layout-annotations.jsp | 14 ++++++ 4 files changed, 67 insertions(+), 23 deletions(-) create mode 100644 apps/showcase/src/main/java/org/apache/struts2/showcase/tiles/TilesAnnotationsAction.java create mode 100644 apps/showcase/src/main/webapp/WEB-INF/tiles/layout-annotations.jsp diff --git a/apps/showcase/src/main/java/org/apache/struts2/showcase/tiles/TilesAnnotationsAction.java b/apps/showcase/src/main/java/org/apache/struts2/showcase/tiles/TilesAnnotationsAction.java new file mode 100644 index 000000000..997db11f8 --- /dev/null +++ b/apps/showcase/src/main/java/org/apache/struts2/showcase/tiles/TilesAnnotationsAction.java @@ -0,0 +1,21 @@ +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; + +} diff --git a/apps/showcase/src/main/webapp/WEB-INF/tiles.xml b/apps/showcase/src/main/webapp/WEB-INF/tiles.xml index 027f9a459..d644502ff 100644 --- a/apps/showcase/src/main/webapp/WEB-INF/tiles.xml +++ b/apps/showcase/src/main/webapp/WEB-INF/tiles.xml @@ -45,4 +45,10 @@ + + + + + + diff --git a/apps/showcase/src/main/webapp/WEB-INF/tiles/body.jsp b/apps/showcase/src/main/webapp/WEB-INF/tiles/body.jsp index e2e35126f..ca9d10df8 100644 --- a/apps/showcase/src/main/webapp/WEB-INF/tiles/body.jsp +++ b/apps/showcase/src/main/webapp/WEB-INF/tiles/body.jsp @@ -1,24 +1,27 @@ -<%@taglib prefix="s" uri="/struts-tags" %> -
-
-
-
-

This example illustrates the Struts/Tiles Plugin.

- -

Tiles 2 is an effort to extract the Tiles library from Struts. It is currently housed - in the Sandbox area of the Apache Struts Subversion repository.

- -

Features

- - -
-
-
+<%@taglib prefix="s" uri="/struts-tags" %> +
+
+
+
+

This example illustrates the Struts/Tiles Plugin.

+ +

Tiles 2 is an effort to extract the Tiles library from Struts. It is currently housed + in the Sandbox area of the Apache Struts Subversion repository.

+ +

Features

+ + +
+
+
\ No newline at end of file diff --git a/apps/showcase/src/main/webapp/WEB-INF/tiles/layout-annotations.jsp b/apps/showcase/src/main/webapp/WEB-INF/tiles/layout-annotations.jsp new file mode 100644 index 000000000..5609cb1a1 --- /dev/null +++ b/apps/showcase/src/main/webapp/WEB-INF/tiles/layout-annotations.jsp @@ -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 --%> + + + Struts2 Showcase - <tiles:getAsString name="title"/> + + + +

Notice that this is a layout made in JSP

+

It is configured with annotations!

+ + From d76357fd829a3ea8ddca21d625c49b606cca88d5 Mon Sep 17 00:00:00 2001 From: cnenning Date: Mon, 25 Jan 2016 11:23:10 +0100 Subject: [PATCH 04/11] added tests for StrutsTilesAnnotationProcessor --- .../tiles/StrutsTilesAnnotationProcessor.java | 7 +- .../TestStrutsTilesAnnotationProcessor.java | 148 ++++++++++++++++++ .../TilesTestActionMultipleAnnotations.java | 12 ++ .../TilesTestActionSingleAnnotation.java | 49 ++++++ ...lesTestActionSingleAnnotationAllEmpty.java | 28 ++++ 5 files changed, 241 insertions(+), 3 deletions(-) create mode 100644 plugins/tiles/src/test/java/org/apache/struts2/tiles/TestStrutsTilesAnnotationProcessor.java create mode 100644 plugins/tiles/src/test/java/org/apache/struts2/tiles/TilesTestActionMultipleAnnotations.java create mode 100644 plugins/tiles/src/test/java/org/apache/struts2/tiles/TilesTestActionSingleAnnotation.java create mode 100644 plugins/tiles/src/test/java/org/apache/struts2/tiles/TilesTestActionSingleAnnotationAllEmpty.java diff --git a/plugins/tiles/src/main/java/org/apache/struts2/tiles/StrutsTilesAnnotationProcessor.java b/plugins/tiles/src/main/java/org/apache/struts2/tiles/StrutsTilesAnnotationProcessor.java index 2ae3ba4c9..fa5f7352f 100644 --- a/plugins/tiles/src/main/java/org/apache/struts2/tiles/StrutsTilesAnnotationProcessor.java +++ b/plugins/tiles/src/main/java/org/apache/struts2/tiles/StrutsTilesAnnotationProcessor.java @@ -66,9 +66,10 @@ public class StrutsTilesAnnotationProcessor { break; } } - } - if (tilesDefinitions.value().length > 0) { - tilesDefinition = tilesDefinitions.value()[0]; + } else { + if (tilesDefinitions.value().length > 0) { + tilesDefinition = tilesDefinitions.value()[0]; + } } } diff --git a/plugins/tiles/src/test/java/org/apache/struts2/tiles/TestStrutsTilesAnnotationProcessor.java b/plugins/tiles/src/test/java/org/apache/struts2/tiles/TestStrutsTilesAnnotationProcessor.java new file mode 100644 index 000000000..db808cdcf --- /dev/null +++ b/plugins/tiles/src/test/java/org/apache/struts2/tiles/TestStrutsTilesAnnotationProcessor.java @@ -0,0 +1,148 @@ +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 TestStrutsTilesAnnotationProcessor { + + @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 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 addListValue = getListValue(addListAttribute); + Assert.assertEquals(1, addListValue.size()); + Assert.assertEquals("list-list-add-attr", addListValue.get(0).getValue()); + + Set 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.getRenderer()); + 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 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 addListValue = getListValue(addListAttribute); + Assert.assertEquals(1, addListValue.size()); + Assert.assertNull(addListValue.get(0).getValue()); + + Set cascadedAttributeNames = definition.getCascadedAttributeNames(); + Assert.assertNull(cascadedAttributeNames); + } + + @SuppressWarnings("unchecked") + protected List getListValue(Attribute listAttribute) { + return (List) listAttribute.getValue(); + } +} diff --git a/plugins/tiles/src/test/java/org/apache/struts2/tiles/TilesTestActionMultipleAnnotations.java b/plugins/tiles/src/test/java/org/apache/struts2/tiles/TilesTestActionMultipleAnnotations.java new file mode 100644 index 000000000..99a736bb6 --- /dev/null +++ b/plugins/tiles/src/test/java/org/apache/struts2/tiles/TilesTestActionMultipleAnnotations.java @@ -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 { + +} diff --git a/plugins/tiles/src/test/java/org/apache/struts2/tiles/TilesTestActionSingleAnnotation.java b/plugins/tiles/src/test/java/org/apache/struts2/tiles/TilesTestActionSingleAnnotation.java new file mode 100644 index 000000000..c7a98ebff --- /dev/null +++ b/plugins/tiles/src/test/java/org/apache/struts2/tiles/TilesTestActionSingleAnnotation.java @@ -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 { + +} diff --git a/plugins/tiles/src/test/java/org/apache/struts2/tiles/TilesTestActionSingleAnnotationAllEmpty.java b/plugins/tiles/src/test/java/org/apache/struts2/tiles/TilesTestActionSingleAnnotationAllEmpty.java new file mode 100644 index 000000000..4a9aff9d3 --- /dev/null +++ b/plugins/tiles/src/test/java/org/apache/struts2/tiles/TilesTestActionSingleAnnotationAllEmpty.java @@ -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 { + +} From a53deac7ce8732053edd43dddac329448055aef0 Mon Sep 17 00:00:00 2001 From: cnenning Date: Mon, 25 Jan 2016 13:39:47 +0100 Subject: [PATCH 05/11] updated javadoc --- .../tiles/annotation/TilesDefinition.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/plugins/tiles/src/main/java/org/apache/struts2/tiles/annotation/TilesDefinition.java b/plugins/tiles/src/main/java/org/apache/struts2/tiles/annotation/TilesDefinition.java index a71bbc3be..1618b63c1 100644 --- a/plugins/tiles/src/main/java/org/apache/struts2/tiles/annotation/TilesDefinition.java +++ b/plugins/tiles/src/main/java/org/apache/struts2/tiles/annotation/TilesDefinition.java @@ -27,6 +27,26 @@ import java.lang.annotation.Target; /** * Represents a <definition> element in tiles.xml. * + *

+ * With a sample layout in tiles.xml like this: + *

+ *      <definition name="layout" template="/WEB-INF/tiles/layout.jsp">
+ *          <put-attribute name="header" value=".header"/>
+ *          <put-attribute name="body" value=".body"/>
+ *      </definition>
+ *  
+ *

+ *

+ * You can annotate an action like that: + *

+ *      @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 {
+ *  
+ *

+ * */ @Retention(value = RetentionPolicy.RUNTIME) @Target(value = { ElementType.TYPE }) From b1588ddc84d876a676bab66ad80ec34637e98536 Mon Sep 17 00:00:00 2001 From: cnenning Date: Mon, 25 Jan 2016 13:50:45 +0100 Subject: [PATCH 06/11] fixed line endings --- .../src/main/webapp/WEB-INF/tiles.xml | 108 +++--- .../src/main/webapp/WEB-INF/tiles/body.jsp | 52 +-- .../struts2/views/tiles/TilesResult.java | 326 +++++++++--------- 3 files changed, 243 insertions(+), 243 deletions(-) diff --git a/apps/showcase/src/main/webapp/WEB-INF/tiles.xml b/apps/showcase/src/main/webapp/WEB-INF/tiles.xml index d644502ff..a74de1b6b 100644 --- a/apps/showcase/src/main/webapp/WEB-INF/tiles.xml +++ b/apps/showcase/src/main/webapp/WEB-INF/tiles.xml @@ -1,54 +1,54 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/showcase/src/main/webapp/WEB-INF/tiles/body.jsp b/apps/showcase/src/main/webapp/WEB-INF/tiles/body.jsp index ca9d10df8..855a89688 100644 --- a/apps/showcase/src/main/webapp/WEB-INF/tiles/body.jsp +++ b/apps/showcase/src/main/webapp/WEB-INF/tiles/body.jsp @@ -1,27 +1,27 @@ -<%@taglib prefix="s" uri="/struts-tags" %> -
-
-
-
-

This example illustrates the Struts/Tiles Plugin.

- -

Tiles 2 is an effort to extract the Tiles library from Struts. It is currently housed - in the Sandbox area of the Apache Struts Subversion repository.

- -

Features

- - -
-
-
+<%@taglib prefix="s" uri="/struts-tags" %> +
+
+
+
+

This example illustrates the Struts/Tiles Plugin.

+ +

Tiles 2 is an effort to extract the Tiles library from Struts. It is currently housed + in the Sandbox area of the Apache Struts Subversion repository.

+ +

Features

+ + +
+
+
\ No newline at end of file diff --git a/plugins/tiles/src/main/java/org/apache/struts2/views/tiles/TilesResult.java b/plugins/tiles/src/main/java/org/apache/struts2/views/tiles/TilesResult.java index da0076575..4656f913a 100644 --- a/plugins/tiles/src/main/java/org/apache/struts2/views/tiles/TilesResult.java +++ b/plugins/tiles/src/main/java/org/apache/struts2/views/tiles/TilesResult.java @@ -1,163 +1,163 @@ -/* - * $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.struts2.views.tiles; - -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; -import org.apache.tiles.request.servlet.ServletUtil; - -/** - * - * Renders a view using struts-tiles. - * - * - * - * In your web.xml file, you need to add a TilesListener. - * - * <listener> - * <listener-class>org.apache.struts2.tiles.StrutsTilesListener</listener-class> - * </listener> - * - * - * - * In struts.xml, use type="tiles" on your <result>. - * - * <action name="editUser" class="userAction" method="edit"> - * <result name="success" type="tiles">userForm</result> - * <result name="input" type="tiles">userList</result> - * </action> - * - * - * - * - * - * Making this result type the default for the current package. - * - * <result-types> - * <result-type name="tiles" - * class="org.apache.struts2.views.tiles.TilesResult" default="true" /> - * </result-types> - * - * - * - * - * You have to configure tiles itself. Therefore you can add tiles.xml either - * to resources or WEB-INF. You may also use annotations like {@link TilesDefinition}. - * - * - * - */ -public class TilesResult extends ServletDispatcherResult { - - private static final long serialVersionUID = -3806939435493086244L; - - private static final Logger LOG = LogManager.getLogger(TilesResult.class); - - public TilesResult() { - super(); - } - - public TilesResult(String location) { - super(location); - } - - /** - * Dispatches to the given location. Does its forward via a RequestDispatcher. If the - * dispatch fails a 404 error will be sent back in the http response. - * - * @param location the location to dispatch to. - * @param invocation the execution state of the action - * @throws Exception if an error occurs. If the dispatch fails the error will go back via the - * 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)) { - // 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(); - - ApplicationContext applicationContext = ServletUtil.getApplicationContext(servletContext); - TilesContainer container = TilesAccess.getContainer(applicationContext); - - HttpServletRequest httpRequest = ServletActionContext.getRequest(); - HttpServletResponse httpResponse = ServletActionContext.getResponse(); - - 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) { - // tilesDefinition not found yet, search 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); - } -} +/* + * $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.struts2.views.tiles; + +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; +import org.apache.tiles.request.servlet.ServletUtil; + +/** + * + * Renders a view using struts-tiles. + * + * + * + * In your web.xml file, you need to add a TilesListener. + * + * <listener> + * <listener-class>org.apache.struts2.tiles.StrutsTilesListener</listener-class> + * </listener> + * + * + * + * In struts.xml, use type="tiles" on your <result>. + * + * <action name="editUser" class="userAction" method="edit"> + * <result name="success" type="tiles">userForm</result> + * <result name="input" type="tiles">userList</result> + * </action> + * + * + * + * + * + * Making this result type the default for the current package. + * + * <result-types> + * <result-type name="tiles" + * class="org.apache.struts2.views.tiles.TilesResult" default="true" /> + * </result-types> + * + * + * + * + * You have to configure tiles itself. Therefore you can add tiles.xml either + * to resources or WEB-INF. You may also use annotations like {@link TilesDefinition}. + * + * + * + */ +public class TilesResult extends ServletDispatcherResult { + + private static final long serialVersionUID = -3806939435493086244L; + + private static final Logger LOG = LogManager.getLogger(TilesResult.class); + + public TilesResult() { + super(); + } + + public TilesResult(String location) { + super(location); + } + + /** + * Dispatches to the given location. Does its forward via a RequestDispatcher. If the + * dispatch fails a 404 error will be sent back in the http response. + * + * @param location the location to dispatch to. + * @param invocation the execution state of the action + * @throws Exception if an error occurs. If the dispatch fails the error will go back via the + * 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)) { + // 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(); + + ApplicationContext applicationContext = ServletUtil.getApplicationContext(servletContext); + TilesContainer container = TilesAccess.getContainer(applicationContext); + + HttpServletRequest httpRequest = ServletActionContext.getRequest(); + HttpServletResponse httpResponse = ServletActionContext.getResponse(); + + 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) { + // tilesDefinition not found yet, search 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); + } +} From 9ca6eb9813ae65a6dd245071825fb9abf63a2a94 Mon Sep 17 00:00:00 2001 From: cnenning Date: Mon, 25 Jan 2016 14:36:07 +0100 Subject: [PATCH 07/11] renamed test class to stick to naming convention --- ...onProcessor.java => StrutsTilesAnnotationProcessorTest.java} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename plugins/tiles/src/test/java/org/apache/struts2/tiles/{TestStrutsTilesAnnotationProcessor.java => StrutsTilesAnnotationProcessorTest.java} (97%) diff --git a/plugins/tiles/src/test/java/org/apache/struts2/tiles/TestStrutsTilesAnnotationProcessor.java b/plugins/tiles/src/test/java/org/apache/struts2/tiles/StrutsTilesAnnotationProcessorTest.java similarity index 97% rename from plugins/tiles/src/test/java/org/apache/struts2/tiles/TestStrutsTilesAnnotationProcessor.java rename to plugins/tiles/src/test/java/org/apache/struts2/tiles/StrutsTilesAnnotationProcessorTest.java index db808cdcf..acaacce5e 100644 --- a/plugins/tiles/src/test/java/org/apache/struts2/tiles/TestStrutsTilesAnnotationProcessor.java +++ b/plugins/tiles/src/test/java/org/apache/struts2/tiles/StrutsTilesAnnotationProcessorTest.java @@ -11,7 +11,7 @@ import org.junit.Test; import org.junit.Assert; -public class TestStrutsTilesAnnotationProcessor { +public class StrutsTilesAnnotationProcessorTest { @Test public void findAnnotationSingleAction() { From edf7c099e3ed6ee17008a738ef8801c854139fd1 Mon Sep 17 00:00:00 2001 From: cnenning Date: Mon, 1 Feb 2016 09:36:23 +0100 Subject: [PATCH 08/11] formatted annotations more nicely --- .../struts2/showcase/tiles/TilesAnnotationsAction.java | 5 +++-- .../org/apache/struts2/tiles/annotation/TilesDefinition.java | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/showcase/src/main/java/org/apache/struts2/showcase/tiles/TilesAnnotationsAction.java b/apps/showcase/src/main/java/org/apache/struts2/showcase/tiles/TilesAnnotationsAction.java index 997db11f8..b5c62f07f 100644 --- a/apps/showcase/src/main/java/org/apache/struts2/showcase/tiles/TilesAnnotationsAction.java +++ b/apps/showcase/src/main/java/org/apache/struts2/showcase/tiles/TilesAnnotationsAction.java @@ -12,8 +12,9 @@ import com.opensymphony.xwork2.ActionSupport; @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"), }) + @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; diff --git a/plugins/tiles/src/main/java/org/apache/struts2/tiles/annotation/TilesDefinition.java b/plugins/tiles/src/main/java/org/apache/struts2/tiles/annotation/TilesDefinition.java index 1618b63c1..3aa144c68 100644 --- a/plugins/tiles/src/main/java/org/apache/struts2/tiles/annotation/TilesDefinition.java +++ b/plugins/tiles/src/main/java/org/apache/struts2/tiles/annotation/TilesDefinition.java @@ -42,7 +42,8 @@ import java.lang.annotation.Target; * @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"), }) + * @TilesPutAttribute(name = "body", value = "/WEB-INF/tiles/body.ftl") + * }) * public class FooAction extends ActionSupport { * *

From 92302703f2430ee6077fa93f0eabd6dbfc497d9a Mon Sep 17 00:00:00 2001 From: cnenning Date: Mon, 1 Feb 2016 09:37:25 +0100 Subject: [PATCH 09/11] added missing license header --- .../showcase/tiles/TilesAnnotationsAction.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/apps/showcase/src/main/java/org/apache/struts2/showcase/tiles/TilesAnnotationsAction.java b/apps/showcase/src/main/java/org/apache/struts2/showcase/tiles/TilesAnnotationsAction.java index b5c62f07f..2b789c2d8 100644 --- a/apps/showcase/src/main/java/org/apache/struts2/showcase/tiles/TilesAnnotationsAction.java +++ b/apps/showcase/src/main/java/org/apache/struts2/showcase/tiles/TilesAnnotationsAction.java @@ -1,3 +1,21 @@ +/* + * 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; From 8651545aaa34dad22c16969f5697cb5b1055f591 Mon Sep 17 00:00:00 2001 From: cnenning Date: Mon, 1 Feb 2016 09:44:22 +0100 Subject: [PATCH 10/11] turned comments into LOG.trace() --- .../main/java/org/apache/struts2/views/tiles/TilesResult.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/tiles/src/main/java/org/apache/struts2/views/tiles/TilesResult.java b/plugins/tiles/src/main/java/org/apache/struts2/views/tiles/TilesResult.java index 4656f913a..ecbdceee3 100644 --- a/plugins/tiles/src/main/java/org/apache/struts2/views/tiles/TilesResult.java +++ b/plugins/tiles/src/main/java/org/apache/struts2/views/tiles/TilesResult.java @@ -115,7 +115,7 @@ public class TilesResult extends ServletDispatcherResult { String actionName = invocation.getInvocationContext().getName(); if (StringUtils.isEmpty(location)) { - // location not set -> action must have one @TilesDefinition + 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; @@ -142,7 +142,7 @@ public class TilesResult extends ServletDispatcherResult { } if (!definitionValid) { if (tilesDefinition == null) { - // tilesDefinition not found yet, search in action + LOG.trace("tilesDefinition not found yet, searching in action"); tilesDefinition = annotationProcessor.findAnnotation(action, location); } if (tilesDefinition != null) { From f5ef1438aaf4d9841dd5180a470dbe52edd8693e Mon Sep 17 00:00:00 2001 From: cnenning Date: Mon, 1 Feb 2016 09:45:34 +0100 Subject: [PATCH 11/11] removed outcommented line --- .../apache/struts2/tiles/StrutsTilesAnnotationProcessorTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/tiles/src/test/java/org/apache/struts2/tiles/StrutsTilesAnnotationProcessorTest.java b/plugins/tiles/src/test/java/org/apache/struts2/tiles/StrutsTilesAnnotationProcessorTest.java index acaacce5e..c71d10092 100644 --- a/plugins/tiles/src/test/java/org/apache/struts2/tiles/StrutsTilesAnnotationProcessorTest.java +++ b/plugins/tiles/src/test/java/org/apache/struts2/tiles/StrutsTilesAnnotationProcessorTest.java @@ -109,7 +109,6 @@ public class StrutsTilesAnnotationProcessorTest { Assert.assertNull(definition.getExtends()); Attribute templateAttribute = definition.getTemplateAttribute(); Assert.assertNull(templateAttribute.getValue()); - //Assert.assertNull(templateAttribute.getRenderer()); Assert.assertNull(templateAttribute.getRole()); Assert.assertNull(templateAttribute.getExpressionObject());