001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.juneau.rest.server.view; 018 019import java.io.*; 020 021import org.apache.juneau.http.*; 022import org.apache.juneau.rest.server.*; 023import org.apache.juneau.rest.server.servlet.*; 024 025/** 026 * Abstract base for the standalone view-servlet companions of the view mixin resources. 027 * 028 * <p> 029 * Each per-engine bridge module ({@code juneau-rest-server-view-jsp}, 030 * {@code juneau-rest-server-view-freemarker}, {@code juneau-rest-server-view-mustache}, 031 * {@code juneau-rest-server-view-thymeleaf}) ships a thin {@code Basic*Servlet} subclass that: 032 * 033 * <ol class='spaced-list'> 034 * <li>Declares its own sibling top-level mount via {@link Rest#paths() @Rest(paths)} (e.g. 035 * {@code "/jsp/*"}), so the servlet is registered as a sibling of the host application's other 036 * servlets ({@code /rest/*}, {@code /jsp/*}, ...) rather than composed under a host root. 037 * <li>Supplies the per-engine {@link RawTemplateDispatcher} (the matching flavor-neutral 038 * {@code <Engine>Dispatcher} worker) via {@link #dispatcher()}. 039 * </ol> 040 * 041 * <p> 042 * The single greedy op declared here ({@code @RestGet(path="/*")}) captures the trailing remainder 043 * under the servlet's mount and delegates straight to the shared {@link RawTemplateDispatcher}. 044 * Because the mixin and standalone forms both route through the same {@code RawTemplateDispatcher} 045 * implementation, their raw file-serving behavior cannot drift. 046 * 047 * <h5 class='section'>Standalone vs mixin:</h5> 048 * 049 * <p> 050 * The mixin {@code Basic*Resource} keeps its op pinned at {@code /<token>/*} for composition into a 051 * host at {@code /}; the standalone {@code Basic*Servlet} moves the mount to the class level 052 * ({@code @Rest(paths="/<token>/*")}) and pins the op at {@code /*}, eliminating the path-doubling 053 * that a mixin-shaped op would otherwise produce when the servlet itself is mounted at 054 * {@code /<token>/*}. 055 * 056 * <h5 class='section'>See Also:</h5><ul> 057 * <li class='jic'>{@link RawTemplateDispatcher} 058 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerComposition">REST Server — Mixins and Multi-Mount Paths</a> 059 * </ul> 060 * 061 * @serial exclude 062 * @since 10.0.0 063 */ 064@Rest 065public abstract class ViewServlet extends RestServlet { 066 067 private static final long serialVersionUID = 1L; 068 069 /** 070 * Returns the per-engine {@link RawTemplateDispatcher} this servlet delegates raw template 071 * dispatch to. 072 * 073 * <p> 074 * Typically the matching flavor-neutral {@code <Engine>Dispatcher} worker (which implements 075 * {@link RawTemplateDispatcher}). Never {@code null}. 076 * 077 * @return The raw-template dispatcher. Never {@code null}. 078 */ 079 protected abstract RawTemplateDispatcher dispatcher(); 080 081 /** 082 * [GET /*] — render the raw template identified by the trailing path under this servlet's 083 * sibling top-level mount. 084 * 085 * <p> 086 * The {@code @Path("/*") String path} captures the multi-segment remainder after the mount 087 * prefix (e.g. a request for {@code /jsp/admin/dashboard.jsp} on a servlet mounted at 088 * {@code /jsp/*} matches with {@code path = "admin/dashboard.jsp"}). Delegates verbatim to the 089 * shared {@link RawTemplateDispatcher}. 090 * 091 * @param path The trailing path segment after the mount prefix. 092 * @param req The current REST request. 093 * @param res The current REST response. 094 * @throws IOException If the underlying response writer fails. 095 */ 096 @RestGet( 097 path="/*", 098 summary="View", 099 description="Render a raw template under this servlet's sibling top-level mount.", 100 swagger=@OpSwagger(ignore=true) 101 ) 102 public void render(@Path("/*") String path, RestRequest req, RestResponse res) throws IOException { 103 dispatcher().render(path, req, res); 104 } 105}