View Javadoc
1   /*
2    * $Id$
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   * http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  package org.apache.tiles.web.util;
22  
23  import java.io.IOException;
24  
25  import javax.servlet.ServletException;
26  import javax.servlet.ServletRequest;
27  import javax.servlet.http.HttpServlet;
28  import javax.servlet.http.HttpServletRequest;
29  import javax.servlet.http.HttpServletResponse;
30  
31  import org.apache.tiles.AttributeContext;
32  import org.apache.tiles.TilesContainer;
33  import org.apache.tiles.reflect.ClassUtil;
34  import org.apache.tiles.servlet.context.ServletUtil;
35  import org.slf4j.Logger;
36  import org.slf4j.LoggerFactory;
37  
38  /**
39   * Tiles dispatching servlet.  Used to invoke
40   * a definition directly.
41   */
42  public class TilesDispatchServlet extends HttpServlet {
43  
44      /**
45       * Init parameter to define the key of the container to use.
46       *
47       * @since 2.1.2
48       */
49      public static final String CONTAINER_KEY_INIT_PARAMETER =
50          "org.apache.tiles.web.util.TilesDispatchServlet.CONTAINER_KEY";
51  
52      /**
53       * The logging object.
54       */
55      private final Logger log = LoggerFactory
56              .getLogger(TilesDispatchServlet.class);
57  
58      /**
59       * The key under which the container is stored.
60       */
61      private String containerKey;
62  
63      /**
64       * The object that will mutate the attribute context so that it uses
65       * different attributes.
66       */
67      private AttributeContextMutator mutator;
68  
69  
70      /** {@inheritDoc} */
71      public void init() throws ServletException {
72          super.init();
73  
74          containerKey = getServletConfig().getInitParameter(
75                  CONTAINER_KEY_INIT_PARAMETER);
76  
77          String temp = getInitParameter("mutator");
78          if (temp != null) {
79              try {
80                  mutator = (AttributeContextMutator) ClassUtil.instantiate(temp);
81              } catch (Exception e) {
82                  throw new ServletException("Unable to instantiate specified context mutator.", e);
83              }
84          } else {
85              mutator = new DefaultMutator();
86          }
87      }
88  
89      /** {@inheritDoc} */
90      protected void doGet(HttpServletRequest req, HttpServletResponse res)
91          throws ServletException, IOException {
92  
93          TilesContainer container = ServletUtil.getContainer(
94                  getServletContext(), containerKey);
95          mutator.mutate(container.getAttributeContext(req, res), req);
96          String definition = getDefinitionName(req);
97          if (log.isDebugEnabled()) {
98              log.info("Dispatching to tile '" + definition + "'");
99          }
100         container.render(definition, req, res);
101     }
102 
103     /**
104      * Returns the called definition name for the given request.
105      *
106      * @param request The request to parse.
107      * @return The definition name to render.
108      */
109     protected String getDefinitionName(HttpServletRequest request) {
110         String path = (String) request.getAttribute("javax.servlet.include.servlet_path");
111         if (path == null) {
112             path = request.getServletPath();
113         }
114 
115         int start = path.startsWith("/") ? 1 : 0;
116         int end = path.endsWith(".tiles") ? path.indexOf(".tiles") : path.length();
117 
118         return path.substring(start, end);
119     }
120 
121     /** {@inheritDoc} */
122     protected void doPost(HttpServletRequest req, HttpServletResponse res)
123         throws ServletException, IOException {
124         log.info("Tiles dispatch request received. Redirecting POST to GET.");
125         doGet(req, res);
126     }
127 
128     /**
129      * Default no-op mutator.
130      */
131     class DefaultMutator implements AttributeContextMutator {
132 
133         /** {@inheritDoc} */
134         public void mutate(AttributeContext context, ServletRequest request) {
135             // noop;
136         }
137     }
138 }