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.ops; 018 019import org.apache.juneau.rest.server.*; 020import org.apache.juneau.rest.server.beans.*; 021import org.apache.juneau.rest.server.servlet.*; 022 023/** 024 * Mixin providing the group-navigation endpoint ({@code [GET /]}) that lists the host resource's child 025 * resources. 026 * 027 * <p> 028 * Single-responsibility op-mixin carved out of the former {@code BasicGroupOperations} interface (and the 029 * concrete {@code getChildren(...)} method previously kept on the {@code Basic*Group} base classes). The 030 * navigation page renders one entry per {@link Rest#children() @Rest(children)} resource declared on the 031 * host. 032 * 033 * <h5 class='section'>Reaching the host's children:</h5> 034 * 035 * <p> 036 * A mixin's {@code @RestOp} methods are bound to a per-mixin {@link RestContext} sub-context that has no 037 * children of its own, so this op resolves the host's children via {@link RestMixin#getHostContext() 038 * getHostContext()}{@code .getRestChildren()} rather than against the mixin's own (empty) context. Because 039 * {@code getHostContext()} is backed by the sub-context's already-populated parent linkage, this works 040 * whether the mixin is composed onto a servlet host or a child-resource host. 041 * 042 * <h5 class='section'>Page decoration:</h5> 043 * 044 * <p> 045 * Per the mixin sub-context inheritance model, the navigation page inherits the host's class-level 046 * {@link org.apache.juneau.marshall.html.HtmlDocConfig @HtmlDocConfig} page decoration (navigation links, 047 * etc.), so the rendered HTML matches the host's other endpoints. 048 * 049 * <h5 class='figure'>Composition example:</h5> 050 * 051 * <p class='bjava'> 052 * <ja>@Rest</ja>(mixins=NavigationMixin.<jk>class</jk>, children={Foo.<jk>class</jk>, Bar.<jk>class</jk>}) 053 * <jk>public class</jk> RootResource <jk>extends</jk> RestServlet { ... } 054 * </p> 055 * 056 * <h5 class='section'>See Also:</h5><ul> 057 * <li class='jc'>{@link ChildResourceDescriptions} 058 * <li class='jm'>{@link RestMixin#getHostContext()} 059 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerComposition">REST Server — Mixins and Multi-Mount Paths</a> 060 * </ul> 061 * 062 * @since 10.0.0 063 */ 064@Rest 065public class NavigationMixin extends RestMixin { 066 067 /** No-arg constructor — navigation has no configurable state. */ 068 public NavigationMixin() { /* intentionally empty */ } 069 070 /** 071 * [GET /] - Get child resources. 072 * 073 * <p> 074 * Returns a bean that lists and allows navigation to the host resource's child resources, resolved 075 * against the {@linkplain RestMixin#getHostContext() host context} so the listing reflects the host's 076 * children rather than the mixin's own (empty) sub-context. 077 * 078 * @param req The HTTP request. 079 * @return The bean containing links to the child resources. 080 */ 081 @RestGet(path="/", summary="Navigation page") 082 public ChildResourceDescriptions getChildren(RestRequest req) { 083 return new ChildResourceDescriptions(getHostContext(), req); 084 } 085}