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 &mdash; 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}