View Javadoc
1   /*
2    * #%L
3    * wcm.io
4    * %%
5    * Copyright (C) 2014 wcm.io
6    * %%
7    * Licensed under the Apache License, Version 2.0 (the "License");
8    * you may not use this file except in compliance with the License.
9    * You may obtain a copy of the License at
10   *
11   *      http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   * #L%
19   */
20  package io.wcm.handler.commons.servlets.impl;
21  
22  import java.io.IOException;
23  
24  import javax.servlet.RequestDispatcher;
25  import javax.servlet.Servlet;
26  import javax.servlet.ServletException;
27  import javax.servlet.http.HttpServletResponse;
28  
29  import org.apache.sling.api.SlingHttpServletRequest;
30  import org.apache.sling.api.SlingHttpServletResponse;
31  import org.apache.sling.api.request.RequestPathInfo;
32  import org.apache.sling.api.servlets.HttpConstants;
33  import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
34  import org.apache.sling.servlets.annotations.SlingServletResourceTypes;
35  import org.jetbrains.annotations.NotNull;
36  import org.osgi.service.component.annotations.Component;
37  import org.osgi.service.component.annotations.ConfigurationPolicy;
38  import org.osgi.service.metatype.annotations.AttributeDefinition;
39  import org.osgi.service.metatype.annotations.Designate;
40  import org.osgi.service.metatype.annotations.ObjectClassDefinition;
41  import org.slf4j.Logger;
42  import org.slf4j.LoggerFactory;
43  
44  import com.day.cq.wcm.api.NameConstants;
45  
46  import io.wcm.wcm.commons.contenttype.FileExtension;
47  
48  /**
49   * Virtually maps an *.htx request to a cq:Page resource to a *.html request internally (because components
50   * and JSPs are normally only registered to *.html extension). Mapping can be enabled or disabled.
51   */
52  @Component(service = Servlet.class, configurationPolicy = ConfigurationPolicy.REQUIRE)
53  @SlingServletResourceTypes(
54      resourceTypes = NameConstants.NT_PAGE,
55      methods = HttpConstants.METHOD_GET,
56      extensions = FileExtension.HTML_UNCACHED
57  )
58  @Designate(ocd = HtxPageExtensionMapper.Config.class)
59  public class HtxPageExtensionMapper extends SlingSafeMethodsServlet {
60    private static final long serialVersionUID = 1L;
61  
62    @ObjectClassDefinition(name = "wcm.io htx Page Extension Mapper",
63        description = "Mapps all *.htx requests on Pages to *.html view.")
64    @interface Config {
65  
66      @AttributeDefinition(name = "Enabled", description = "Enable mapping.")
67      boolean enabled() default false;
68  
69    }
70  
71    private static final Logger log = LoggerFactory.getLogger(HtxPageExtensionMapper.class);
72  
73    private boolean enabled;
74  
75    // ---------- SCR Integration ----------------------------------------------
76  
77    protected void activate(Config config) {
78      // read config
79      this.enabled = config.enabled();
80    }
81  
82    @Override
83    protected void doGet(@NotNull SlingHttpServletRequest request, @NotNull SlingHttpServletResponse response) throws ServletException, IOException {
84  
85      // if not enabled: sent http 404
86      if (!enabled) {
87        response.sendError(HttpServletResponse.SC_NOT_FOUND);
88        return;
89      }
90  
91      // rebuild requested url, but use "html" as extension instead of "htx"
92      // to allow re-using all component definitions that are registered to "html"
93      RequestPathInfo info = request.getRequestPathInfo();
94      StringBuilder url = new StringBuilder();
95      url.append(info.getResourcePath());
96      if (info.getSelectorString() != null) {
97        url.append('.').append(info.getSelectorString());
98      }
99      url.append('.').append(FileExtension.HTML); // use html extension instead of .htx extension
100     if (info.getSuffix() != null) {
101       url.append('/').append(info.getSuffix());
102     }
103 
104     if (log.isDebugEnabled()) {
105       log.debug("Dispatch request {} to {}", request.getRequestURI(), url);
106     }
107 
108     // execute request with *.html extension
109     RequestDispatcher requestDispatcher = request.getRequestDispatcher(url.toString());
110     if (requestDispatcher != null) {
111       requestDispatcher.include(request, response);
112     }
113     else {
114       throw new ServletException("No Request Dispatcher.");
115     }
116 
117   }
118 
119 }