You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by cn...@apache.org on 2016/02/03 10:53:37 UTC

[02/13] struts git commit: Added tiles annotations, see WW-4594.

Added tiles annotations, see WW-4594.

Added tiles annotations, created StrutsTilesAnnotationProcessor to
create Definitons from them and using it in TilesResult.

Project: http://git-wip-us.apache.org/repos/asf/struts/repo
Commit: http://git-wip-us.apache.org/repos/asf/struts/commit/9ac326aa
Tree: http://git-wip-us.apache.org/repos/asf/struts/tree/9ac326aa
Diff: http://git-wip-us.apache.org/repos/asf/struts/diff/9ac326aa

Branch: refs/heads/master
Commit: 9ac326aa2458fe43140c1b13b61c87752d282e3d
Parents: d9f4054
Author: cnenning <cn...@apache.org>
Authored: Fri Jan 22 15:27:09 2016 +0100
Committer: cnenning <cn...@apache.org>
Committed: Fri Jan 22 15:27:09 2016 +0100

----------------------------------------------------------------------
 .../tiles/StrutsTilesAnnotationProcessor.java   | 176 ++++++++++++
 .../tiles/annotation/TilesAddAttribute.java     |  30 ++
 .../tiles/annotation/TilesAddListAttribute.java |  28 ++
 .../tiles/annotation/TilesDefinition.java       |  45 +++
 .../tiles/annotation/TilesDefinitions.java      |  36 +++
 .../tiles/annotation/TilesPutAttribute.java     |  32 +++
 .../tiles/annotation/TilesPutListAttribute.java |  32 +++
 .../apache/struts2/views/tiles/TilesResult.java | 279 +++++++++++--------
 8 files changed, 542 insertions(+), 116 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/struts/blob/9ac326aa/plugins/tiles/src/main/java/org/apache/struts2/tiles/StrutsTilesAnnotationProcessor.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 0000000..2ae3ba4
--- /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 <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;
+                    }
+                }
+            }
+            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;
+    }
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/9ac326aa/plugins/tiles/src/main/java/org/apache/struts2/tiles/annotation/TilesAddAttribute.java
----------------------------------------------------------------------
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 0000000..0e668de
--- /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 <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 "";
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/9ac326aa/plugins/tiles/src/main/java/org/apache/struts2/tiles/annotation/TilesAddListAttribute.java
----------------------------------------------------------------------
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 0000000..d65066f
--- /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 <code>&lt;add-list-attribute&gt;</code> element in <code>tiles.xml</code>.
+ *
+ */
+public @interface TilesAddListAttribute {
+    String role() default "";
+    TilesAddAttribute[] addAttributes() default {};
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/9ac326aa/plugins/tiles/src/main/java/org/apache/struts2/tiles/annotation/TilesDefinition.java
----------------------------------------------------------------------
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 0000000..a71bbc3
--- /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 <code>&lt;definition&gt;</code> element in <code>tiles.xml</code>.
+ *
+ */
+@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 {};
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/9ac326aa/plugins/tiles/src/main/java/org/apache/struts2/tiles/annotation/TilesDefinitions.java
----------------------------------------------------------------------
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 0000000..fb5cc95
--- /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();
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/9ac326aa/plugins/tiles/src/main/java/org/apache/struts2/tiles/annotation/TilesPutAttribute.java
----------------------------------------------------------------------
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 0000000..c31d49e
--- /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 <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 "";
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/9ac326aa/plugins/tiles/src/main/java/org/apache/struts2/tiles/annotation/TilesPutListAttribute.java
----------------------------------------------------------------------
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 0000000..be7a507
--- /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 <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 {};
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/9ac326aa/plugins/tiles/src/main/java/org/apache/struts2/views/tiles/TilesResult.java
----------------------------------------------------------------------
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 a402869..da00765 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;
-
-/**
- * <!-- START SNIPPET: description -->
- * Renders a view using struts-tiles.
- * <!-- 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.
- *
- * &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;
- * <!-- END SNIPPET: webxml -->
- *
- * <!-- START SNIPPET: strutsxml -->
- * In struts.xml, use type="tiles" on your &lt;result&gt;.
- *
- * &lt;action name="editUser" class="userAction" method="edit"&gt;
- *      &lt;result name="success" type="tiles"&gt;userForm&lt;/result&gt;
- *      &lt;result name="input" type="tiles"&gt;userList&lt;/result&gt;
- * &lt;/action&gt;
- * <!-- END SNIPPET: strutsxml -->
- *
- *
- * <!-- START SNIPPET: packageconfig -->
- *
- * Making this result type the default for the current package.
- *
- * &lt;result-types&gt;
- *      &lt;result-type name="tiles"
- * class="org.apache.struts2.views.tiles.TilesResult" default="true" /&gt;
- * &lt;/result-types&gt;
- * <!-- END SNIPPET: packageconfig -->
- *
- */
-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;
+
+/**
+ * <!-- START SNIPPET: description -->
+ * Renders a view using struts-tiles.
+ * <!-- END SNIPPET: description -->
+ *
+ * <!-- START SNIPPET: webxml -->
+ * In your web.xml file, you need to add a TilesListener.
+ *
+ * &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 -->
+ * In struts.xml, use type="tiles" on your &lt;result&gt;.
+ *
+ * &lt;action name="editUser" class="userAction" method="edit"&gt;
+ *      &lt;result name="success" type="tiles"&gt;userForm&lt;/result&gt;
+ *      &lt;result name="input" type="tiles"&gt;userList&lt;/result&gt;
+ * &lt;/action&gt;
+ * <!-- END SNIPPET: strutsxml -->
+ *
+ *
+ * <!-- START SNIPPET: packageconfig -->
+ *
+ * Making this result type the default for the current package.
+ *
+ * &lt;result-types&gt;
+ *      &lt;result-type name="tiles"
+ * class="org.apache.struts2.views.tiles.TilesResult" default="true" /&gt;
+ * &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();
+    }
+
+    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);
+    }
+}