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} — 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 — 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 * — 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}) — 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="<property>")} cuts the corresponding {@code @Child} seed too, 060 * for both buckets above — 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}