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;
018
019import static java.lang.annotation.RetentionPolicy.*;
020
021import java.lang.annotation.*;
022
023import org.apache.juneau.marshall.httppart.*;
024import org.apache.juneau.rest.server.converter.*;
025import org.apache.juneau.rest.server.guard.*;
026
027/**
028 * Host-side setting seed for the {@link Rest#childrenDefs() @Rest(childrenDefs=...)} attribute.
029 *
030 * <p>
031 * Declares a routed child class <b>and</b> lets the <i>host</i> seed a curated set of {@code @Rest}-level
032 * settings onto that child's otherwise-isolated {@link RestContext} &mdash; the child-resource analog of
033 * {@link Rest#mixinDefs() @Rest(mixinDefs=...)}. This is the host-side complement to
034 * {@link Rest#children() @Rest(children=...)} (which takes bare classes and offers no seed hook).
035 *
036 * <h5 class='section'>Example:</h5>
037 * <p class='bjava'>
038 *    <ja>@Rest</ja>(
039 *       childrenDefs=<ja>@Child</ja>(type=FooChild.<jk>class</jk>, maxInput=<js>"10M"</js>)
040 *    )
041 *    <jk>public class</jk> MyResource { ... }
042 * </p>
043 *
044 * <h5 class='section'>Seed semantics</h5>
045 * <p>
046 * Unlike {@link Mixin @Mixin} overrides (which win over an <i>inherited</i> chain), children are
047 * <b>isolated</b> from the host's resolution chain by design, so a {@code @Child} seed doesn't override
048 * anything &mdash; it seeds settings onto an otherwise-isolated child context:
049 * <ul>
050 *    <li><b>Additive-security</b> ({@code guards}, {@code converters}, {@code roleGuard}, {@code rolesDeclared})
051 *       &mdash; the host contributes, the child can't remove or weaken it (list-shaped members prepend; the two
052 *       role-based members AND-stack alongside the child's own value).
053 *    <li><b>Child-wins scalars</b> ({@code partSerializer}, {@code partParser},
054 *       {@code defaultCharset}, {@code maxInput}) &mdash; the seed is a default/fallback; the child's own explicit
055 *       {@code @Rest} declaration wins when present.
056 * </ul>
057 *
058 * <p>
059 * A child's own {@code @Rest(noInherit="&lt;property&gt;")} cuts the corresponding {@code @Child} seed too,
060 * for both buckets above &mdash; the child always stays in full control of its own configuration.
061 *
062 * <p>
063 * There is no {@code noInherit()} member on {@code @Child} itself (nothing to cut in an isolated context), and
064 * no {@code path()}/{@code paths()} re-mount member (the child's own {@code @Rest(path)} stays authoritative).
065 *
066 * <h5 class='section'>See Also:</h5><ul>
067 *    <li class='ja'>{@link Rest#childrenDefs()}
068 *    <li class='ja'>{@link Rest#children()}
069 * </ul>
070 *
071 * @since 10.0.0
072 */
073@Target({})
074@Retention(RUNTIME)
075public @interface Child {
076
077   /**
078    * The child class to route.
079    *
080    * <p>
081    * Required. Equivalent to a bare entry in {@link Rest#children()}, but with the seed slots below.
082    *
083    * @return The child class.
084    */
085   Class<?> type();
086
087   //-----------------------------------------------------------------------------------------------------------------
088   // Additive-security seed slots — host contributes, child can't remove or weaken.
089   //-----------------------------------------------------------------------------------------------------------------
090
091   /**
092    * Host-seeded {@link Rest#guards() guards} for this child's endpoints (prepended before the child's own).
093    *
094    * @return The annotation value.
095    */
096   Class<? extends RestGuard>[] guards() default {};
097
098   /**
099    * Host-seeded {@link Rest#converters() converters} for this child's endpoints (prepended before the child's own).
100    *
101    * @return The annotation value.
102    */
103   Class<? extends RestConverter>[] converters() default {};
104
105   /**
106    * Host-seeded {@link Rest#roleGuard() roleGuard} for this child's endpoints (AND-stacks with the child's own).
107    *
108    * @return The annotation value.
109    */
110   String roleGuard() default "";
111
112   /**
113    * Host-seeded {@link Rest#rolesDeclared() rolesDeclared} for this child's endpoints (AND-stacks with the child's own).
114    *
115    * @return The annotation value.
116    */
117   String rolesDeclared() default "";
118
119   //-----------------------------------------------------------------------------------------------------------------
120   // Child-wins scalar seed slots — seed is a default/fallback; the child's own explicit value wins.
121   //-----------------------------------------------------------------------------------------------------------------
122
123   /**
124    * Host-seeded {@link Rest#partSerializer() partSerializer} default for this child's endpoints.
125    *
126    * @return The annotation value.
127    */
128   Class<? extends HttpPartSerializer> partSerializer() default HttpPartSerializer.Void.class;
129
130   /**
131    * Host-seeded {@link Rest#partParser() partParser} default for this child's endpoints.
132    *
133    * @return The annotation value.
134    */
135   Class<? extends HttpPartParser> partParser() default HttpPartParser.Void.class;
136
137   /**
138    * Host-seeded {@link Rest#defaultCharset() defaultCharset} default for this child's endpoints.
139    *
140    * @return The annotation value.
141    */
142   String defaultCharset() default "";
143
144   /**
145    * Host-seeded {@link Rest#maxInput() maxInput} default for this child's endpoints.
146    *
147    * @return The annotation value.
148    */
149   String maxInput() default "";
150}