This is an automated email from the ASF dual-hosted git repository. jamesbognar pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/juneau.git
The following commit(s) were added to refs/heads/master by this push: new 8e8716d Swagger improvements. 8e8716d is described below commit 8e8716d46751e3337e7e71088894d708193af1d3 Author: JamesBognar <jamesbog...@apache.org> AuthorDate: Sun Apr 22 19:07:34 2018 -0400 Swagger improvements. --- .../org/apache/juneau/dto/swagger/HeaderInfo.java | 83 ++- .../org/apache/juneau/dto/swagger/ui/SwaggerUI.css | 2 +- .../org/apache/juneau/internal/ObjectUtils.java | 27 + .../main/java/org/apache/juneau/utils/Value.java | 83 ++- .../org/apache/juneau/utils/ValueListener.java | 20 +- juneau-doc/src/main/javadoc/overview.html | 2 +- .../files/htdocs/styles/SwaggerUI.css | 2 +- .../examples/rest/SystemPropertiesResource.java | 2 +- .../juneau/examples/rest/petstore/IdConflict.java | 2 +- .../juneau/examples/rest/petstore/IdNotFound.java | 2 +- .../juneau/examples/rest/petstore/InvalidId.java | 2 +- .../examples/rest/petstore/InvalidLogin.java | 2 +- .../examples/rest/petstore/InvalidSpecies.java | 2 +- .../juneau/examples/rest/petstore/InvalidTag.java | 2 +- .../examples/rest/petstore/InvalidUsername.java | 2 +- .../examples/rest/petstore/PetStoreResource.java | 20 +- .../microservice/resources/ConfigResource.java | 4 +- .../microservice/resources/DirectoryResource.java | 8 +- .../microservice/resources/LogsResource.java | 8 +- .../apache/juneau/rest/BasicRestCallHandler.java | 6 +- .../apache/juneau/rest/BasicRestInfoProvider.java | 56 +- .../java/org/apache/juneau/rest/RestContext.java | 49 +- .../org/apache/juneau/rest/RestMethodReturn.java | 5 +- .../org/apache/juneau/rest/RestMethodThrown.java | 5 +- .../org/apache/juneau/rest/RestParamDefaults.java | 236 +++++- .../java/org/apache/juneau/rest/RestParamType.java | 9 + .../org/apache/juneau/rest/annotation/Body.java | 20 +- .../apache/juneau/rest/annotation/FormData.java | 2 +- .../apache/juneau/rest/annotation/HasFormData.java | 2 +- .../apache/juneau/rest/annotation/HasQuery.java | 2 +- .../org/apache/juneau/rest/annotation/Header.java | 4 +- .../org/apache/juneau/rest/annotation/Path.java | 2 +- .../org/apache/juneau/rest/annotation/Query.java | 2 +- .../{ResponseInfo.java => Response.java} | 31 +- .../{Header.java => ResponseHeader.java} | 823 +++++++++++---------- .../ResponseStatus.java} | 31 +- .../juneau/rest/annotation/ResponseStatuses.java | 58 +- .../apache/juneau/rest/annotation/Responses.java | 58 +- .../apache/juneau/rest/exception/BadRequest.java | 2 +- .../org/apache/juneau/rest/exception/Conflict.java | 2 +- .../juneau/rest/exception/ExpectationFailed.java | 2 +- .../juneau/rest/exception/FailedDependency.java | 2 +- .../apache/juneau/rest/exception/Forbidden.java | 2 +- .../org/apache/juneau/rest/exception/Gone.java | 2 +- .../rest/exception/HttpVersionNotSupported.java | 2 +- .../juneau/rest/exception/InsufficientStorage.java | 2 +- .../juneau/rest/exception/InternalServerError.java | 2 +- .../juneau/rest/exception/LengthRequired.java | 2 +- .../org/apache/juneau/rest/exception/Locked.java | 2 +- .../apache/juneau/rest/exception/LoopDetected.java | 2 +- .../juneau/rest/exception/MethodNotAllowed.java | 2 +- .../juneau/rest/exception/MisdirectedRequest.java | 2 +- .../exception/NetworkAuthenticationRequired.java | 2 +- .../juneau/rest/exception/NotAcceptable.java | 2 +- .../apache/juneau/rest/exception/NotExtended.java | 2 +- .../org/apache/juneau/rest/exception/NotFound.java | 2 +- .../juneau/rest/exception/NotImplemented.java | 2 +- .../juneau/rest/exception/PayloadTooLarge.java | 2 +- .../juneau/rest/exception/PreconditionFailed.java | 2 +- .../rest/exception/PreconditionRequired.java | 2 +- .../juneau/rest/exception/RangeNotSatisfiable.java | 2 +- .../exception/RequestHeaderFieldsTooLarge.java | 2 +- .../juneau/rest/exception/ServiceUnavailable.java | 2 +- .../juneau/rest/exception/TooManyRequests.java | 2 +- .../apache/juneau/rest/exception/Unauthorized.java | 2 +- .../rest/exception/UnavailableForLegalReasons.java | 2 +- .../juneau/rest/exception/UnprocessableEntity.java | 2 +- .../rest/exception/UnsupportedMediaType.java | 2 +- .../juneau/rest/exception/UpgradeRequired.java | 2 +- .../apache/juneau/rest/exception/UriTooLong.java | 2 +- .../rest/exception/VariantAlsoNegotiates.java | 2 +- .../java/org/apache/juneau/rest/helper/Ok.java | 2 +- .../org/apache/juneau/rest/helper/Redirect.java | 2 +- .../juneau/rest/helper/RedirectToServletRoot.java | 2 +- .../juneau/rest/helper/ResourceDescription.java | 2 +- 75 files changed, 1067 insertions(+), 683 deletions(-) diff --git a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/HeaderInfo.java b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/HeaderInfo.java index e4316fa..0c09d04 100644 --- a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/HeaderInfo.java +++ b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/HeaderInfo.java @@ -49,7 +49,7 @@ import org.apache.juneau.utils.*; * <li class='link'><a class='doclink' href='../../../../../overview-summary.html#juneau-dto.Swagger'>Overview > juneau-dto > Swagger</a> * </ul> */ -@Bean(properties="description,type,format,items,collectionFormat,default,maximum,exclusiveMaximum,minimum,exclusiveMinimum,maxLength,minLength,pattern,maxItems,minItems,uniqueItems,enum,multipleOf,$ref,*") +@Bean(properties="description,type,format,items,collectionFormat,default,maximum,exclusiveMaximum,minimum,exclusiveMinimum,maxLength,minLength,pattern,maxItems,minItems,uniqueItems,enum,multipleOf,$ref,x-examples,*") @SuppressWarnings({"unchecked"}) public class HeaderInfo extends SwaggerElement { @@ -79,6 +79,7 @@ public class HeaderInfo extends SwaggerElement { private Items items; private Object _default; private List<Object> _enum; + private Map<String,String> examples; /** * Default constructor. @@ -111,6 +112,10 @@ public class HeaderInfo extends SwaggerElement { this._default = copyFrom._default; this.items = copyFrom.items == null ? null : copyFrom.items.copy(); this._enum = newList(copyFrom._enum); + + this.examples = copyFrom.examples == null ? null : new LinkedHashMap<String,String>(); + if (copyFrom.examples != null) + this.examples.putAll(copyFrom.examples); } /** @@ -1053,6 +1058,77 @@ public class HeaderInfo extends SwaggerElement { return setRef(value); } + /** + * Bean property getter: <property>x-examples</property>. + * + * @return The property value, or <jk>null</jk> if it is not set. + */ + @BeanProperty("x-examples") + public Map<String,String> getExamples() { + return examples; + } + + /** + * Bean property setter: <property>examples</property>. + * + * @param value + * The new value for this property. + * <br>Can be <jk>null</jk> to unset the property. + * @return This object (for method chaining). + */ + @BeanProperty("x-examples") + public HeaderInfo setExamples(Map<String,String> value) { + examples = newMap(value); + return this; + } + + /** + * Adds one or more values to the <property>examples</property> property. + * + * @param values + * The values to add to this property. + * <br>Ignored if <jk>null</jk>. + * @return This object (for method chaining). + */ + public HeaderInfo addExamples(Map<String,String> values) { + examples = addToMap(examples, values); + return this; + } + + /** + * Adds a single value to the <property>examples</property> property. + * + * @param name The extra property name. + * @param value The extra property value. + * @return This object (for method chaining). + */ + public HeaderInfo example(String name, String value) { + examples = addToMap(examples, name, value); + return this; + } + + /** + * Adds one or more values to the <property>examples</property> property. + * + * @param values + * The values to add to this property. + * <br>Valid types: + * <ul> + * <li><code>Map<String,String></code> + * <li><code>String</code> - JSON object representation of <code>Map<String,Object></code> + * <h5 class='figure'>Example:</h5> + * <p class='bcode'> + * examples(<js>"{'text/json':'{foo:\\'bar\\'}'}"</js>); + * </p> + * </ul> + * <br>Ignored if <jk>null</jk>. + * @return This object (for method chaining). + */ + public HeaderInfo examples(Object...values) { + examples = addToMap(examples, values, String.class, String.class); + return this; + } + @Override /* SwaggerElement */ public <T> T get(String property, Class<T> type) { if (property == null) @@ -1077,6 +1153,7 @@ public class HeaderInfo extends SwaggerElement { case "uniqueItems": return toType(getUniqueItems(), type); case "enum": return toType(getEnum(), type); case "multipleOf": return toType(getMultipleOf(), type); + case "x-examples": return toType(getExamples(), type); default: return super.get(property, type); } } @@ -1105,6 +1182,7 @@ public class HeaderInfo extends SwaggerElement { case "uniqueItems": return uniqueItems(value); case "enum": return setEnum(null)._enum(value); case "multipleOf": return multipleOf(value); + case "x-examples": return examples(value); default: super.set(property, value); return this; @@ -1132,7 +1210,8 @@ public class HeaderInfo extends SwaggerElement { .appendIf(minItems != null, "minItems") .appendIf(uniqueItems != null, "uniqueItems") .appendIf(_enum != null, "enum") - .appendIf(multipleOf != null, "multipleOf"); + .appendIf(multipleOf != null, "multipleOf") + .appendIf(examples != null, "x-examples"); return new MultiSet<>(s, super.keySet()); } diff --git a/juneau-core/juneau-dto/src/main/resources/org/apache/juneau/dto/swagger/ui/SwaggerUI.css b/juneau-core/juneau-dto/src/main/resources/org/apache/juneau/dto/swagger/ui/SwaggerUI.css index b118da2..e1c8a21 100644 --- a/juneau-core/juneau-dto/src/main/resources/org/apache/juneau/dto/swagger/ui/SwaggerUI.css +++ b/juneau-core/juneau-dto/src/main/resources/org/apache/juneau/dto/swagger/ui/SwaggerUI.css @@ -332,7 +332,7 @@ div.headers { } .section-table { - display: inline-block; +/* display: inline-block;*/ } .responses .section-table td { diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ObjectUtils.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ObjectUtils.java index 98adf11..9ac2f32 100644 --- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ObjectUtils.java +++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ObjectUtils.java @@ -309,4 +309,31 @@ public final class ObjectUtils { public static Enum<?>[] getEnumConstants(Class<?> c) { return ((Class<Enum<?>>)c).getEnumConstants(); } + + /** + * If the specified object is an instance of the specified class, casts it to that type. + * + * @param o The object to cast. + * @param c The class to cast to. + * @return The cast object, or <jk>null</jk> if the object wasn't an instance of the specified class. + */ + @SuppressWarnings("unchecked") + public static <T> T castOrNull(Object o, Class<T> c) { + if (c.isInstance(o)) + return (T)o; + return null; + } + + /** + * Returns the first non-zero value in the list of ints. + * + * @param ints The ints to check. + * @return The first non-zero value, or <code>0</code> if they were all zero. + */ + public static int firstNonZero(int...ints) { + for (int i : ints) + if (i != 0) + return i; + return 0; + } } diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/ResponseInfo.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/Value.java similarity index 60% copy from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/ResponseInfo.java copy to juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/Value.java index 3c300b9..452d8ac 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/ResponseInfo.java +++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/Value.java @@ -10,56 +10,75 @@ // * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * // * specific language governing permissions and limitations under the License. * // *************************************************************************************************************************** -package org.apache.juneau.rest.annotation; - -import static java.lang.annotation.ElementType.*; -import static java.lang.annotation.RetentionPolicy.*; - -import java.lang.annotation.*; +package org.apache.juneau.utils; /** - * Annotation that can be applied to exceptions and return types that identify the HTTP status they trigger and a description about the exception. + * Represents a simple settable value. + * + * <p> + * This object is not thread safe. + * + * @param <T> The value type. */ -@Documented -@Target(TYPE) -@Retention(RUNTIME) -@Inherited -public @interface ResponseInfo { +public class Value<T> { + + private T t; + private ValueListener<T> listener; /** - * The HTTP status of the response. + * Constructor. */ - int code() default 0; - + public Value() { + } + /** - * Description. + * Constructor. * - * <p> - * Format is plain text. + * @param t Initial value. */ - String description() default ""; - + public Value(T t) { + set(t); + } + /** - * Schema information. + * Adds a listener for this value. * - * <p> - * Format is a JSON object consisting of a Swagger SchemaInfo object. + * @param listener The new listener for this value. + * @return This object (for method chaining). */ - String[] schema() default {}; + public Value<T> listener(ValueListener<T> listener) { + this.listener = listener; + return this; + } /** - * Header information. + * Sets the value. * - * <p> - * Format is a JSON array consisting of Swagger HeaderInfo objects. + * @param t The new value. + * @return This object (for method chaining). */ - String[] headers() default {}; + public Value<T> set(T t) { + this.t = t; + if (listener != null) + listener.onSet(t); + return this; + } /** - * Example. + * Returns the value. + * + * @return The value, or <jk>null</jk> if it is not set. + */ + public T get() { + return t; + } + + /** + * Returns <jk>true</jk> if the value is set. * - * <p> - * Format is a JSON primitive, array, or object. + * @return <jk>true</jk> if the value is set. */ - String[] example() default {}; + public boolean isSet() { + return get() != null; + } } diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/InvalidSpecies.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/ValueListener.java similarity index 78% copy from juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/InvalidSpecies.java copy to juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/ValueListener.java index d856988..25fefa0 100644 --- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/InvalidSpecies.java +++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/ValueListener.java @@ -10,22 +10,18 @@ // * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * // * specific language governing permissions and limitations under the License. * // *************************************************************************************************************************** -package org.apache.juneau.examples.rest.petstore; - -import org.apache.juneau.rest.annotation.*; -import org.apache.juneau.rest.exception.*; +package org.apache.juneau.utils; /** - * Exception thrown when an invalid species is looked up. + * Simple listener for the {@link Value} class. + * @param <T> */ -@SuppressWarnings("serial") -@ResponseInfo(description="Invalid species provided") -public class InvalidSpecies extends BadRequest { +public interface ValueListener<T> { /** - * Constructor. + * Called when {@link Value#set(Object)} is called. + * + * @param newValue The new value. */ - public InvalidSpecies() { - super("Invalid species provided."); - } + void onSet(T newValue); } diff --git a/juneau-doc/src/main/javadoc/overview.html b/juneau-doc/src/main/javadoc/overview.html index 8b37669..75f9ce4 100644 --- a/juneau-doc/src/main/javadoc/overview.html +++ b/juneau-doc/src/main/javadoc/overview.html @@ -21286,7 +21286,7 @@ <li> Newlines were being stripped from <code><ja>@HtmlDoc</ja>(script)</code> when serialized which could cause script lines to become commented out. <li> - New {@link org.apache.juneau.rest.annotation.ResponseInfo @ResponseInfo} annotation that can be applied to + New {@link org.apache.juneau.rest.annotation.Response @Response} and {@link org.apache.juneau.rest.annotation.Responses @Responses} annotations that can be applied to throwables thrown from REST methods and POJOs returned by REST methods to specify non-200 status return codes and descriptions in Swagger documentation. <li> Swagger fields added to the following annotations: diff --git a/juneau-examples/juneau-examples-rest/files/htdocs/styles/SwaggerUI.css b/juneau-examples/juneau-examples-rest/files/htdocs/styles/SwaggerUI.css index b118da2..e1c8a21 100644 --- a/juneau-examples/juneau-examples-rest/files/htdocs/styles/SwaggerUI.css +++ b/juneau-examples/juneau-examples-rest/files/htdocs/styles/SwaggerUI.css @@ -332,7 +332,7 @@ div.headers { } .section-table { - display: inline-block; +/* display: inline-block;*/ } .responses .section-table td { diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SystemPropertiesResource.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SystemPropertiesResource.java index dc1faf2..e2fcf1e 100644 --- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SystemPropertiesResource.java +++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SystemPropertiesResource.java @@ -222,7 +222,7 @@ public class SystemPropertiesResource extends BasicRestServlet { // Beans //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - @ResponseInfo( description="User is not an administrator.") + @Response(description="User is not an administrator.") public static class UserNotAdminException extends Forbidden { private static final long serialVersionUID = 1L; diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/IdConflict.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/IdConflict.java index 7b1f07b..f7d5b37 100644 --- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/IdConflict.java +++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/IdConflict.java @@ -19,7 +19,7 @@ import org.apache.juneau.rest.exception.*; * Exception thrown when trying to add an entry where the ID is already in use. */ @SuppressWarnings("serial") -@ResponseInfo(description="ID already in use") +@Response(description="ID already in use") public class IdConflict extends Conflict { /** diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/IdNotFound.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/IdNotFound.java index 6fd2e43..fc5c53c 100644 --- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/IdNotFound.java +++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/IdNotFound.java @@ -19,7 +19,7 @@ import org.apache.juneau.rest.exception.*; * Exception thrown when trying to add an entry where the ID is already in use. */ @SuppressWarnings("serial") -@ResponseInfo(description="ID not found") +@Response(description="ID not found") public class IdNotFound extends NotFound { /** diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/InvalidId.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/InvalidId.java index 88848dd..0c1e430 100644 --- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/InvalidId.java +++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/InvalidId.java @@ -19,7 +19,7 @@ import org.apache.juneau.rest.exception.*; * Exception thrown when trying to add an entry where the ID is already in use. */ @SuppressWarnings("serial") -@ResponseInfo(description="Invalid ID provided") +@Response(description="Invalid ID provided") public class InvalidId extends BadRequest { /** diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/InvalidLogin.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/InvalidLogin.java index 4fc42e4..2053b17 100644 --- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/InvalidLogin.java +++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/InvalidLogin.java @@ -19,7 +19,7 @@ import org.apache.juneau.rest.exception.*; * Exception thrown when an invalid username or password is provided. */ @SuppressWarnings("serial") -@ResponseInfo(description="Invalid username or password provided") +@Response(description="Invalid username or password provided") public class InvalidLogin extends Unauthorized { /** diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/InvalidSpecies.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/InvalidSpecies.java index d856988..d5f987d 100644 --- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/InvalidSpecies.java +++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/InvalidSpecies.java @@ -19,7 +19,7 @@ import org.apache.juneau.rest.exception.*; * Exception thrown when an invalid species is looked up. */ @SuppressWarnings("serial") -@ResponseInfo(description="Invalid species provided") +@Response(description="Invalid species provided") public class InvalidSpecies extends BadRequest { /** diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/InvalidTag.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/InvalidTag.java index 3d1e4b2..3f3643c 100644 --- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/InvalidTag.java +++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/InvalidTag.java @@ -19,7 +19,7 @@ import org.apache.juneau.rest.exception.*; * Exception thrown when trying to add an entry where the ID is already in use. */ @SuppressWarnings("serial") -@ResponseInfo(description="Invalid tag provided") +@Response(description="Invalid tag provided") public class InvalidTag extends BadRequest { /** diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/InvalidUsername.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/InvalidUsername.java index d830f82..c35fea5 100644 --- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/InvalidUsername.java +++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/InvalidUsername.java @@ -19,7 +19,7 @@ import org.apache.juneau.rest.exception.*; * Exception thrown when trying to add an entry where the ID is already in use. */ @SuppressWarnings("serial") -@ResponseInfo(description="Invalid username provided") +@Response(description="Invalid username provided") public class InvalidUsername extends BadRequest { /** diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/PetStoreResource.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/PetStoreResource.java index 1ee8ba3..0c0773d 100644 --- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/PetStoreResource.java +++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/PetStoreResource.java @@ -33,6 +33,7 @@ import org.apache.juneau.rest.exception.*; import org.apache.juneau.rest.helper.*; import org.apache.juneau.rest.widget.*; import org.apache.juneau.transforms.*; +import org.apache.juneau.utils.*; import org.apache.juneau.rest.converters.*; /** @@ -581,20 +582,14 @@ public class PetStoreResource extends BasicRestServletJena { path="/user/login", summary="Logs user into the system", swagger=@MethodSwagger( - tags="user", - responses={ - "200:{", - "headers:{", - "X-Rate-Limit:{ type:'integer', format:'int32', description:'calls per hour allowed by the user', 'x-example':123},", - "X-Expires-After:{ type:'string', format:'date-time', description:'date in UTC when token expires', 'x-example':'2012-10-21'}", - "}", - "}" - } + tags="user" ) ) public Ok login( @Query(name="username", description="The username for login", required="true", example="myuser") String username, @Query(name="password", description="The password for login in clear text", required="true", example="abc123") String password, + @ResponseHeader(name="X-Rate-Limit", type="integer", format="int32", description="Calls per hour allowed by the user.", example="123") Value<Integer> rateLimit, + ExpiresAfter expiresAfter, RestRequest req, RestResponse res ) throws InvalidLogin, NotAcceptable { @@ -604,10 +599,13 @@ public class PetStoreResource extends BasicRestServletJena { Date d = new Date(System.currentTimeMillis() + 30 * 60 * 1000); req.getSession().setAttribute("login-expires", d); - res.setHeader("X-Rate-Limit", "1000"); - res.setHeader("X-Expires-After", DateUtils.formatDate(d)); + rateLimit.set(1000); + expiresAfter.set(DateUtils.formatDate(d)); return OK; } + + @ResponseHeader(name="X-Expires-After", type="string", format="date-time", description="Date in UTC when token expires", example="20120-10-21") + public static class ExpiresAfter extends Value<String> {} @RestMethod( name="GET", diff --git a/juneau-microservice/juneau-microservice-server/src/main/java/org/apache/juneau/microservice/resources/ConfigResource.java b/juneau-microservice/juneau-microservice-server/src/main/java/org/apache/juneau/microservice/resources/ConfigResource.java index 5203a2b..40b476a 100755 --- a/juneau-microservice/juneau-microservice-server/src/main/java/org/apache/juneau/microservice/resources/ConfigResource.java +++ b/juneau-microservice/juneau-microservice-server/src/main/java/org/apache/juneau/microservice/resources/ConfigResource.java @@ -202,7 +202,7 @@ public class ConfigResource extends BasicRestServlet { // Helper beans //----------------------------------------------------------------------------------------------------------------- - @ResponseInfo(description="Section not found.") + @Response(description="Section not found.") private class SectionNotFound extends NotFound { private static final long serialVersionUID = 1L; @@ -211,7 +211,7 @@ public class ConfigResource extends BasicRestServlet { } } - @ResponseInfo(description="The configuration file contained syntax errors and could not be parsed.") + @Response(description="The configuration file contained syntax errors and could not be parsed.") private class BadConfig extends InternalServerError { private static final long serialVersionUID = 1L; diff --git a/juneau-microservice/juneau-microservice-server/src/main/java/org/apache/juneau/microservice/resources/DirectoryResource.java b/juneau-microservice/juneau-microservice-server/src/main/java/org/apache/juneau/microservice/resources/DirectoryResource.java index 732b108..870e0af 100755 --- a/juneau-microservice/juneau-microservice-server/src/main/java/org/apache/juneau/microservice/resources/DirectoryResource.java +++ b/juneau-microservice/juneau-microservice-server/src/main/java/org/apache/juneau/microservice/resources/DirectoryResource.java @@ -209,24 +209,24 @@ public class DirectoryResource extends BasicRestServlet { // Helper beans //----------------------------------------------------------------------------------------------------------------- - @ResponseInfo(schema="{schema:{type:'string',format:'binary'}}", description="Contents of file") + @Response(schema="{schema:{type:'string',format:'binary'}}", description="Contents of file") static class FileContents extends FileInputStream { public FileContents(File file) throws FileNotFoundException { super(file); } } - @ResponseInfo(description="Redirect to root page on success") + @Response(description="Redirect to root page on success") static class RedirectToRoot extends RedirectToServletRoot {} - @ResponseInfo(description="File action") + @Response(description="File action") public static class Action extends LinkString { public Action(String name, String uri, Object...uriArgs) { super(name, uri, uriArgs); } } - @ResponseInfo(description="File or directory details") + @Response(description="File or directory details") @Bean(properties="type,name,size,lastModified,actions,files") public class FileResource { private final File f; diff --git a/juneau-microservice/juneau-microservice-server/src/main/java/org/apache/juneau/microservice/resources/LogsResource.java b/juneau-microservice/juneau-microservice-server/src/main/java/org/apache/juneau/microservice/resources/LogsResource.java index aa8c40d..fe1cf8e 100755 --- a/juneau-microservice/juneau-microservice-server/src/main/java/org/apache/juneau/microservice/resources/LogsResource.java +++ b/juneau-microservice/juneau-microservice-server/src/main/java/org/apache/juneau/microservice/resources/LogsResource.java @@ -249,24 +249,24 @@ public class LogsResource extends BasicRestServlet { // Helper beans //----------------------------------------------------------------------------------------------------------------- - @ResponseInfo(schema="{schema:{type:'string',format:'binary'}}", description="Contents of file") + @Response(schema="{schema:{type:'string',format:'binary'}}", description="Contents of file") static class FileContents extends FileInputStream { public FileContents(File file) throws FileNotFoundException { super(file); } } - @ResponseInfo(description="Redirect to root page on success") + @Response(description="Redirect to root page on success") static class RedirectToRoot extends RedirectToServletRoot {} - @ResponseInfo(description="File action") + @Response(description="File action") public static class Action extends LinkString { public Action(String name, String uri, Object...uriArgs) { super(name, uri, uriArgs); } } - @ResponseInfo(description="File or directory details") + @Response(description="File or directory details") @Bean(properties="type,name,size,lastModified,actions,files") public static class FileResource { private final File f; diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestCallHandler.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestCallHandler.java index 5077ae3..b0d007b 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestCallHandler.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestCallHandler.java @@ -23,6 +23,7 @@ import java.util.*; import javax.servlet.*; import javax.servlet.http.*; +import org.apache.juneau.internal.*; import org.apache.juneau.rest.annotation.*; import org.apache.juneau.rest.exception.*; import org.apache.juneau.rest.helper.*; @@ -193,8 +194,9 @@ public class BasicRestCallHandler implements RestCallHandler { r1.setAttribute("ExecTime", System.currentTimeMillis() - startTime); handleError(r1, r2, e); } catch (Throwable e) { - ResponseInfo ri = e.getClass().getAnnotation(ResponseInfo.class); - RestException e2 = new RestException(e, ri == null || ri.code() == 0 ? SC_INTERNAL_SERVER_ERROR : ri.code()); + Response ri = e.getClass().getAnnotation(Response.class); + int code = ri == null ? SC_INTERNAL_SERVER_ERROR : ObjectUtils.firstNonZero(ri.code(), ri.value(), SC_INTERNAL_SERVER_ERROR); + RestException e2 = new RestException(e, code); r1.setAttribute("Exception", e); r1.setAttribute("ExecTime", System.currentTimeMillis() - startTime); handleError(r1, r2, e2); diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestInfoProvider.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestInfoProvider.java index bdf6aea..3f8c4f2 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestInfoProvider.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestInfoProvider.java @@ -326,7 +326,7 @@ public class BasicRestInfoProvider implements RestInfoProvider { RestParamType in = mp.getParamType(); - if (in == OTHER) + if (in == OTHER || in == RESPONSE || in == RESPONSE_HEADER || in == RESPONSE_STATUS) continue; String key = in.toString() + '.' + (in == BODY ? null : mp.getName()); @@ -386,7 +386,7 @@ public class BasicRestInfoProvider implements RestInfoProvider { } } - // Gather responses from @ResponseInfo-annotated exceptions. + // Gather responses from @Response-annotated exceptions. for (RestMethodThrown rt : context.getRestMethodThrowns(m)) { int code = rt.getCode(); if (code != 0) { @@ -421,6 +421,58 @@ public class BasicRestInfoProvider implements RestInfoProvider { responses.getObjectMap(key).appendIf(false, true, true, "description", RestUtils.getHttpResponseText(Integer.parseInt(key))); } + // Finally, look for @ResponseHeader parameters defined on method. + for (RestMethodParam mp : context.getRestMethodParams(m)) { + + RestParamType in = mp.getParamType(); + + if (in == RESPONSE_HEADER) { + ObjectMap pi = mp.getMetaData(); + String code = pi.getString("status", "200"); + String name = mp.getName(); + + ObjectMap header = responses.getObjectMap(code, true).getObjectMap("headers", true).getObjectMap(name, true); + + header.appendIf(false, true, true, "description", vr.resolve(pi.getString("description"))); + header.appendIf(false, true, true, "type", vr.resolve(pi.getString("type"))); + header.appendIf(false, true, true, "format", vr.resolve(pi.getString("format"))); + header.appendIf(false, true, true, "collectionFormat", vr.resolve(pi.getString("collectionFormat"))); + header.appendIf(false, true, true, "maximum", vr.resolve(pi.getString("maximum"))); + header.appendIf(false, true, true, "minimum", vr.resolve(pi.getString("minimum"))); + header.appendIf(false, true, true, "multipleOf", vr.resolve(pi.getString("multipleOf"))); + header.appendIf(false, true, true, "maxLength", vr.resolve(pi.getString("maxLength"))); + header.appendIf(false, true, true, "minLength", vr.resolve(pi.getString("minLength"))); + header.appendIf(false, true, true, "maxItems", vr.resolve(pi.getString("maxItems"))); + header.appendIf(false, true, true, "minItems", vr.resolve(pi.getString("minItems"))); + header.appendIf(false, true, true, "exclusiveMaximum", vr.resolve(pi.getString("exclusiveMaximum"))); + header.appendIf(false, true, true, "exclusiveMimimum", vr.resolve(pi.getString("exclusiveMimimum"))); + header.appendIf(false, true, true, "uniqueItems", vr.resolve(pi.getString("uniqueItems"))); + header.appendIf(false, true, true, "default", JsonParser.DEFAULT.parse(vr.resolve(pi.getString("default")), Object.class)); + header.appendIf(false, true, true, "enum", parseList(pi.getString("enum"), vr, false, true, "ParameterInfo/enum on class {0} method {1}", c, m)); + header.appendIf(false, true, true, "x-example", parseAnything(vr.resolve(pi.getString("example")))); + if (pi.containsKeyNotEmpty("items")) + header.appendIf(false, true, true, "items", new ObjectMap(vr.resolve(pi.getString("items")))); + + } else if (in == RESPONSE) { + ObjectMap pi = mp.getMetaData(); + String code = pi.getString("status", "200"); + + ObjectMap response = responses.getObjectMap(code, true); + + response.appendIf(false, true, true, "description", vr.resolve(pi.getString("description"))); + response.appendIf(false, true, true, "schema", vr.resolve(pi.getString("schema"))); + response.appendIf(false, true, true, "x-example", parseAnything(vr.resolve(pi.getString("example")))); + + } else if (in == RESPONSE_STATUS) { + ObjectMap pi = mp.getMetaData(); + String code = pi.getString("status", "200"); + + ObjectMap response = responses.getObjectMap(code, true); + + response.appendIf(false, true, true, "description", vr.resolve(pi.getString("description"))); + } + } + if (responses.isEmpty()) op.remove("responses"); else diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java index 867e90b..b5ea4e8 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java @@ -17,6 +17,7 @@ import static org.apache.juneau.internal.ClassUtils.*; import static org.apache.juneau.internal.CollectionUtils.*; import static org.apache.juneau.internal.IOUtils.*; import static org.apache.juneau.internal.StringUtils.*; +import static org.apache.juneau.internal.ObjectUtils.*; import java.io.*; import java.lang.annotation.*; @@ -4274,25 +4275,65 @@ public final class RestContext extends BeanContext { rp[i] = paramResolvers.get(c); if (rp[i] == null) rp[i] = RestParamDefaults.STANDARD_RESOLVERS.get(c); + for (Annotation a : c.getAnnotations()) { + if (a instanceof Header) + rp[i] = new RestParamDefaults.HeaderObject(method, (Header)a, t, ps, rp[i]); + else if (a instanceof FormData) + rp[i] = new RestParamDefaults.FormDataObject(method, (FormData)a, t, ps, rp[i]); + else if (a instanceof Query) + rp[i] = new RestParamDefaults.QueryObject(method, (Query)a, t, ps, rp[i]); + else if (a instanceof HasFormData) + rp[i] = new RestParamDefaults.HasFormDataObject(method, (HasFormData)a, t); + else if (a instanceof HasQuery) + rp[i] = new RestParamDefaults.HasQueryObject(method, (HasQuery)a, t); + else if (a instanceof Body) + rp[i] = new RestParamDefaults.BodyObject(method, (Body)a, t, null); + else if (a instanceof PathRemainder) + rp[i] = new RestParamDefaults.PathRemainderObject(method, t); + else if (a instanceof Response) + rp[i] = new RestParamDefaults.ResponseObject(method, (Response)a, t, ps, rp[i]); + else if (a instanceof ResponseHeader) + rp[i] = new RestParamDefaults.ResponseHeaderObject(method, (ResponseHeader)a, t, ps, rp[i]); + else if (a instanceof ResponseStatus) + rp[i] = new RestParamDefaults.ResponseStatusObject(method, (ResponseStatus)a, t, ps, rp[i]); + else if (a instanceof Responses) + for (Response r : ((Responses)a).value()) + rp[i] = new RestParamDefaults.ResponseObject(method, r, t, ps, rp[i]); + else if (a instanceof ResponseStatuses) + for (ResponseStatus rs : ((ResponseStatuses)a).value()) + rp[i] = new RestParamDefaults.ResponseStatusObject(method, rs, t, ps, rp[i]); + } } for (Annotation a : pa[i]) { if (a instanceof Header) - rp[i] = new RestParamDefaults.HeaderObject(method, (Header)a, t, ps); + rp[i] = new RestParamDefaults.HeaderObject(method, (Header)a, t, ps, rp[i]); else if (a instanceof FormData) - rp[i] = new RestParamDefaults.FormDataObject(method, (FormData)a, t, ps); + rp[i] = new RestParamDefaults.FormDataObject(method, (FormData)a, t, ps, rp[i]); else if (a instanceof Query) - rp[i] = new RestParamDefaults.QueryObject(method, (Query)a, t, ps); + rp[i] = new RestParamDefaults.QueryObject(method, (Query)a, t, ps, rp[i]); else if (a instanceof HasFormData) rp[i] = new RestParamDefaults.HasFormDataObject(method, (HasFormData)a, t); else if (a instanceof HasQuery) rp[i] = new RestParamDefaults.HasQueryObject(method, (HasQuery)a, t); else if (a instanceof Body) - rp[i] = new RestParamDefaults.BodyObject(method, (Body)a, t); + rp[i] = new RestParamDefaults.BodyObject(method, (Body)a, t, rp[i]); else if (a instanceof org.apache.juneau.rest.annotation.Method) rp[i] = new RestParamDefaults.MethodObject(method, t); else if (a instanceof PathRemainder) rp[i] = new RestParamDefaults.PathRemainderObject(method, t); + else if (a instanceof Response) + rp[i] = new RestParamDefaults.ResponseObject(method, (Response)a, t, ps, rp[i]); + else if (a instanceof ResponseHeader) + rp[i] = new RestParamDefaults.ResponseHeaderObject(method, (ResponseHeader)a, t, ps, rp[i]); + else if (a instanceof ResponseStatus) + rp[i] = new RestParamDefaults.ResponseStatusObject(method, (ResponseStatus)a, t, ps, rp[i]); + else if (a instanceof Responses) + for (Response r : ((Responses)a).value()) + rp[i] = new RestParamDefaults.ResponseObject(method, r, t, ps, rp[i]); + else if (a instanceof ResponseStatuses) + for (ResponseStatus rs : ((ResponseStatuses)a).value()) + rp[i] = new RestParamDefaults.ResponseStatusObject(method, rs, t, ps, rp[i]); } if (rp[i] == null) { diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodReturn.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodReturn.java index ccdecc3..e6a11f7 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodReturn.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodReturn.java @@ -35,9 +35,8 @@ public class RestMethodReturn { int code = 200; if (type instanceof Class) - for (ResponseInfo ri : ReflectionUtils.findAnnotationsParentFirst(ResponseInfo.class, (Class<?>)type)) { - if (ri.code() != 0) - code = ri.code(); + for (Response ri : ReflectionUtils.findAnnotationsParentFirst(Response.class, (Class<?>)type)) { + code = ObjectUtils.firstNonZero(ri.code(), ri.value(), code); metaData.appendSkipEmpty("description", ri.description()); metaData.appendSkipEmpty("example", join(ri.example(), "")); metaData.appendSkipEmpty("headers", join(ri.headers(), "")); diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodThrown.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodThrown.java index ff9e511..65203b2 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodThrown.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestMethodThrown.java @@ -34,9 +34,8 @@ public class RestMethodThrown { this.metaData = new ObjectMap(); int code = 500; - for (ResponseInfo ri : ReflectionUtils.findAnnotationsParentFirst(ResponseInfo.class, type)) { - if (ri.code() != 0) - code = ri.code(); + for (Response ri : ReflectionUtils.findAnnotationsParentFirst(Response.class, type)) { + code = ObjectUtils.firstNonZero(ri.code(), ri.value(), code); metaData.appendSkipEmpty("description", ri.description()); metaData.appendSkipEmpty("example", join(ri.example(), "")); metaData.appendSkipEmpty("headers", join(ri.headers(), "")); diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestParamDefaults.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestParamDefaults.java index 3e7f48a..5778f6c 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestParamDefaults.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestParamDefaults.java @@ -13,6 +13,7 @@ package org.apache.juneau.rest; import static org.apache.juneau.internal.StringUtils.*; +import static org.apache.juneau.internal.ObjectUtils.*; import static org.apache.juneau.rest.RestParamType.*; import java.io.*; @@ -30,6 +31,7 @@ import org.apache.juneau.http.*; import org.apache.juneau.http.Date; import org.apache.juneau.httppart.*; import org.apache.juneau.internal.*; +import org.apache.juneau.json.*; import org.apache.juneau.parser.*; import org.apache.juneau.rest.annotation.*; import org.apache.juneau.utils.*; @@ -579,8 +581,8 @@ class RestParamDefaults { static final class BodyObject extends RestMethodParam { - protected BodyObject(Method method, Body a, Type type) { - super(BODY, null, type, getMetaData(a)); + protected BodyObject(Method method, Body a, Type type, RestMethodParam existing) { + super(BODY, null, type, getMetaData(a, castOrNull(existing, BodyObject.class))); } @Override /* RestMethodParam */ @@ -588,11 +590,12 @@ class RestParamDefaults { return req.getBody().asType(type); } - private static final ObjectMap getMetaData(Body a) { + private static final ObjectMap getMetaData(Body a, BodyObject existing) { + ObjectMap om = existing == null ? new ObjectMap() : existing.metaData; if (a == null) - return ObjectMap.EMPTY_MAP; - return new ObjectMap() - .appendSkipEmpty("description", a.description()) + return om; + return om + .appendSkipEmpty("description", join(a.description())) .appendSkipEmpty("required", a.required()) .appendSkipEmpty("type", a.type()) .appendSkipEmpty("format", a.format()) @@ -609,11 +612,11 @@ class RestParamDefaults { .appendSkipEmpty("exclusiveMaximum", a.exclusiveMaximum()) .appendSkipEmpty("exclusiveMimimum", a.exclusiveMimimum()) .appendSkipEmpty("uniqueItems", a.uniqueItems()) - .appendSkipEmpty("schema", a.schema()) - .appendSkipEmpty("default", a._default()) - .appendSkipEmpty("enum", a._enum()) - .appendSkipEmpty("items", a.items()) - .appendSkipEmpty("example", a.example()) + .appendSkipEmpty("schema", join(a.schema())) + .appendSkipEmpty("default", join(a._default())) + .appendSkipEmpty("enum", join(a._enum())) + .appendSkipEmpty("items", join(a.items())) + .appendSkipEmpty("example", join(a.example())) ; } } @@ -621,8 +624,8 @@ class RestParamDefaults { static final class HeaderObject extends RestMethodParam { private final HttpPartParser partParser; - protected HeaderObject(Method method, Header a, Type type, PropertyStore ps) { - super(HEADER, firstNonEmpty(a.name(), a.value()), type, getMetaData(a)); + protected HeaderObject(Method method, Header a, Type type, PropertyStore ps, RestMethodParam existing) { + super(HEADER, firstNonEmpty(a.name(), a.value()), type, getMetaData(a, castOrNull(existing, HeaderObject.class))); this.partParser = a.parser() == HttpPartParser.Null.class ? null : ClassUtils.newInstance(HttpPartParser.class, a.parser(), true, ps); } @@ -631,10 +634,11 @@ class RestParamDefaults { return req.getHeaders().get(partParser, name, type); } - private static ObjectMap getMetaData(Header a) { + private static ObjectMap getMetaData(Header a, HeaderObject existing) { + ObjectMap om = existing == null ? new ObjectMap() : existing.metaData; if (a == null) - return ObjectMap.EMPTY_MAP; - return new ObjectMap() + return om; + return om .appendSkipEmpty("description", a.description()) .appendSkipEmpty("required", a.required()) .appendSkipEmpty("type", a.type()) @@ -650,7 +654,7 @@ class RestParamDefaults { .appendSkipEmpty("minItems", a.minItems()) .appendSkipEmpty("allowEmptyVals", a.allowEmptyVals()) .appendSkipEmpty("exclusiveMaximum", a.exclusiveMaximum()) - .appendSkipEmpty("exclusiveMimimum", a.exclusiveMimimum()) + .appendSkipEmpty("exclusiveMinimum", a.exclusiveMinimum()) .appendSkipEmpty("uniqueItems", a.uniqueItems()) .appendSkipEmpty("schema", a.schema()) .appendSkipEmpty("default", a._default()) @@ -661,6 +665,178 @@ class RestParamDefaults { } } + static final class ResponseHeaderObject extends RestMethodParam { + final HttpPartSerializer partSerializer; + + protected ResponseHeaderObject(Method method, ResponseHeader a, Type type, PropertyStore ps, RestMethodParam existing) { + super(RESPONSE_HEADER, firstNonEmpty(a.name(), a.value(), "Unknown"), type, getMetaData(a, castOrNull(existing, ResponseHeaderObject.class))); + this.partSerializer = a.serializer() == HttpPartSerializer.Null.class ? null : ClassUtils.newInstance(HttpPartSerializer.class, a.serializer(), true, ps); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override /* RestMethodParam */ + public Object resolve(RestRequest req, final RestResponse res) throws Exception { + if (type instanceof Class) { + Class<?> c = (Class<?>)type; + if (ClassUtils.isParentClass(Value.class, c)) { + try { + Value<Object> v = (Value<Object>)c.newInstance(); + v.listener(new ValueListener() { + @Override + public void onSet(Object newValue) { + res.setHeader(name, partSerializer.serialize(HttpPartType.HEADER, newValue)); + } + }); + String def = getMetaData().getString("default"); + if (def != null) { + Class<?> pc = ClassUtils.resolveParameterType(Value.class, 0, c); + v.set(JsonParser.DEFAULT.parse(def, req.getBeanSession().getClassMeta(pc))); + } + + return v; + } catch (Exception e) { + throw new RestException(500, "Invalid type {0} specified with @ResponseHeader annotation. It must have a public no-arg constructor.", type); + } + } + } + throw new RestException(500, "Invalid type {0} specified with @ResponseHeader annotation. It must be a subclass of Value.", type); + } + + public HttpPartSerializer getPartSerializer() { + return partSerializer; + } + + private static ObjectMap getMetaData(ResponseHeader a, ResponseHeaderObject existing) { + ObjectMap om = existing == null ? new ObjectMap() : existing.metaData; + if (a == null) + return om; + String code = firstNonEmpty(a.code(), "200"); + for (String c : StringUtils.split(code)) { + ObjectMap om2 = om.getObjectMap(c, true); + om2 + .appendSkipEmpty("description", join(a.description())) + .appendSkipEmpty("type", a.type()) + .appendSkipEmpty("format", a.format()) + .appendSkipEmpty("collectionFormat", a.collectionFormat()) + .appendSkipEmpty("maximum", a.maximum()) + .appendSkipEmpty("minimum", a.minimum()) + .appendSkipEmpty("multipleOf", a.multipleOf()) + .appendSkipEmpty("maxLength", a.maxLength()) + .appendSkipEmpty("minLength", a.minLength()) + .appendSkipEmpty("maxItems", a.maxItems()) + .appendSkipEmpty("minItems", a.minItems()) + .appendSkipEmpty("exclusiveMaximum", a.exclusiveMaximum()) + .appendSkipEmpty("exclusiveMimimum", a.exclusiveMinimum()) + .appendSkipEmpty("uniqueItems", a.uniqueItems()) + .appendSkipEmpty("default", join(a._default())) + .appendSkipEmpty("enum", join(a._enum())) + .appendSkipEmpty("items", join(a.items())) + .appendSkipEmpty("example", join(a.example())) + ; + } + return om; + } + } + + static final class ResponseObject extends RestMethodParam { + + protected ResponseObject(Method method, Response a, Type type, PropertyStore ps, RestMethodParam existing) { + super(RESPONSE, "body", type, getMetaData(a, castOrNull(existing, ResponseObject.class))); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override /* RestMethodParam */ + public Object resolve(RestRequest req, final RestResponse res) throws Exception { + if (type instanceof Class) { + Class<?> c = (Class<?>)type; + if (ClassUtils.isParentClass(Value.class, c)) { + try { + Value<Object> v = (Value<Object>)c.newInstance(); + v.listener(new ValueListener() { + @Override + public void onSet(Object newValue) { + res.setOutput(newValue); + } + }); + String def = getMetaData().getString("default"); + if (def != null) { + Class<?> pc = ClassUtils.resolveParameterType(Value.class, 0, c); + v.set(JsonParser.DEFAULT.parse(def, req.getBeanSession().getClassMeta(pc))); + } + + return v; + } catch (Exception e) { + throw new RestException(500, "Invalid type {0} specified with @ResponseHeader annotation. It must have a public no-arg constructor.", type); + } + } + } + throw new RestException(500, "Invalid type {0} specified with @ResponseHeader annotation. It must be a subclass of Value.", type); + } + + private static ObjectMap getMetaData(Response a, ResponseObject existing) { + ObjectMap om = existing == null ? new ObjectMap() : existing.metaData; + if (a == null) + return om; + int status = ObjectUtils.firstNonZero(a.code(), a.value(), 200); + ObjectMap om2 = om.getObjectMap(String.valueOf(status), true); + om2 + .appendSkipEmpty("description", join(a.description())) + .appendSkipEmpty("schema", join(a.schema())) + .appendSkipEmpty("headers", join(a.headers())) + .appendSkipEmpty("example", join(a.example())) + ; + return om; + } + } + + static final class ResponseStatusObject extends RestMethodParam { + + protected ResponseStatusObject(Method method, ResponseStatus a, Type type, PropertyStore ps, RestMethodParam existing) { + super(RESPONSE_STATUS, "", type, getMetaData(a, castOrNull(existing, ResponseStatusObject.class))); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override /* RestMethodParam */ + public Object resolve(RestRequest req, final RestResponse res) throws Exception { + if (type instanceof Class) { + Class<?> c = (Class<?>)type; + if (ClassUtils.isParentClass(Value.class, c)) { + try { + Value<Object> v = (Value<Object>)c.newInstance(); + v.listener(new ValueListener() { + @Override + public void onSet(Object newValue) { + res.setStatus(Integer.parseInt(newValue.toString())); + } + }); + String def = getMetaData().getString("default"); + if (def != null) { + Class<?> pc = ClassUtils.resolveParameterType(Value.class, 0, c); + v.set(JsonParser.DEFAULT.parse(def, req.getBeanSession().getClassMeta(pc))); + } + + return v; + } catch (Exception e) { + throw new RestException(500, "Invalid type {0} specified with @ResponseStatus annotation. It must have a public no-arg constructor.", type); + } + } + } + throw new RestException(500, "Invalid type {0} specified with @ResponseStatus annotation. It must be a subclass of Value.", type); + } + + private static ObjectMap getMetaData(ResponseStatus a, ResponseStatusObject existing) { + ObjectMap om = existing == null ? new ObjectMap() : existing.metaData; + if (a == null) + return om; + int status = firstNonZero(a.code(), a.value(), 200); + ObjectMap om2 = om.getObjectMap(String.valueOf(status), true); + om2 + .appendSkipEmpty("description", join(a.description())) + ; + return om; + } + } + static final class MethodObject extends RestMethodParam { protected MethodObject(Method method, Type type) throws ServletException { @@ -679,8 +855,8 @@ class RestParamDefaults { private final boolean multiPart; private final HttpPartParser partParser; - protected FormDataObject(Method method, FormData a, Type type, PropertyStore ps) throws ServletException { - super(FORM_DATA, firstNonEmpty(a.name(), a.value()), type, getMetaData(a)); + protected FormDataObject(Method method, FormData a, Type type, PropertyStore ps, RestMethodParam existing) throws ServletException { + super(FORM_DATA, firstNonEmpty(a.name(), a.value()), type, getMetaData(a, castOrNull(existing, FormDataObject.class))); if (a.multipart() && ! isCollection(type)) throw new RestServletException("Use of multipart flag on @FormData parameter that's not an array or Collection on method ''{0}''", method); this.multiPart = a.multipart(); @@ -694,10 +870,11 @@ class RestParamDefaults { return req.getFormData().get(partParser, name, type); } - private static final ObjectMap getMetaData(FormData a) { + private static final ObjectMap getMetaData(FormData a, FormDataObject existing) { + ObjectMap om = existing == null ? new ObjectMap() : existing.metaData; if (a == null) - return ObjectMap.EMPTY_MAP; - return new ObjectMap() + return om; + return om .appendSkipEmpty("description", a.description()) .appendSkipEmpty("required", a.required()) .appendSkipEmpty("type", a.type()) @@ -728,8 +905,8 @@ class RestParamDefaults { private final boolean multiPart; private final HttpPartParser partParser; - protected QueryObject(Method method, Query a, Type type, PropertyStore ps) throws ServletException { - super(QUERY, firstNonEmpty(a.name(), a.value()), type, getMetaData(a)); + protected QueryObject(Method method, Query a, Type type, PropertyStore ps, RestMethodParam existing) throws ServletException { + super(QUERY, firstNonEmpty(a.name(), a.value()), type, getMetaData(a, castOrNull(existing, QueryObject.class))); if (a.multipart() && ! isCollection(type)) throw new RestServletException("Use of multipart flag on @Query parameter that's not an array or Collection on method ''{0}''", method); this.multiPart = a.multipart(); @@ -743,10 +920,11 @@ class RestParamDefaults { return req.getQuery().get(partParser, name, type); } - private static final ObjectMap getMetaData(Query a) { + private static final ObjectMap getMetaData(Query a, QueryObject existing) { + ObjectMap om = existing == null ? new ObjectMap() : existing.metaData; if (a == null) - return ObjectMap.EMPTY_MAP; - return new ObjectMap() + return om; + return om .appendSkipEmpty("description", a.description()) .appendSkipEmpty("required", a.required()) .appendSkipEmpty("type", a.type()) @@ -1125,4 +1303,8 @@ class RestParamDefaults { static final boolean isCollection(Type t) { return BeanContext.DEFAULT.getClassMeta(t).isCollectionOrArray(); } + + static final String join(String...s) { + return StringUtils.join(s, '\n'); + } } diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestParamType.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestParamType.java index ff913c5..ed51fb2 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestParamType.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestParamType.java @@ -37,6 +37,15 @@ public enum RestParamType { /** Request body */ BODY("body"), + /** Response value */ + RESPONSE("response"), + + /** Response header value */ + RESPONSE_HEADER("responseHeader"), + + /** Response status value */ + RESPONSE_STATUS("responseStatus"), + /** Not a standard Swagger-defined field */ OTHER("other"); diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Body.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Body.java index d3187ff..72f5744 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Body.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Body.java @@ -58,7 +58,7 @@ import org.apache.juneau.rest.*; * </ul> */ @Documented -@Target(PARAMETER) +@Target({PARAMETER,TYPE}) @Retention(RUNTIME) @Inherited public @interface Body { @@ -70,12 +70,13 @@ public @interface Body { * <ul class='spaced-list'> * <li> * The format of the value is plain-text. + * <br>Multiple lines are concatenated with newlines. * <li> * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> * (e.g. <js>"$L{my.localized.variable}"</js>). * </ul> */ - String description() default ""; + String[] description() default {}; /** * Defines the swagger value <code>/paths/{path}/{method}/parameters/#/required</code>. @@ -323,12 +324,13 @@ public @interface Body { * <ul class='spaced-list'> * <li> * The format of the value is a JSON object. + * <br>Multiple lines are concatenated with newlines. * <li> * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> * (e.g. <js>"$L{my.localized.variable}"</js>). * </ul> */ - String schema() default ""; + String[] schema() default {}; /** * Defines the swagger value <code>/paths/{path}/{method}/parameters/#/default</code>. @@ -337,12 +339,13 @@ public @interface Body { * <ul class='spaced-list'> * <li> * The format of the value is JSON. + * <br>Multiple lines are concatenated with newlines. * <li> * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> * (e.g. <js>"$L{my.localized.variable}"</js>). * </ul> */ - String _default() default ""; + String[] _default() default {}; /** * Defines the swagger value <code>/paths/{path}/{method}/parameters/#/enum</code>. @@ -351,12 +354,13 @@ public @interface Body { * <ul class='spaced-list'> * <li> * The format of the value is a JSON array or comma-delimited list. + * <br>Multiple lines are concatenated with newlines. * <li> * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> * (e.g. <js>"$L{my.localized.variable}"</js>). * </ul> */ - String _enum() default ""; + String[] _enum() default {}; /** * Defines the swagger value <code>/paths/{path}/{method}/parameters/#/items</code>. @@ -365,12 +369,13 @@ public @interface Body { * <ul class='spaced-list'> * <li> * The format of the value is a JSON object. + * <br>Multiple lines are concatenated with newlines. * <li> * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> * (e.g. <js>"$L{my.localized.variable}"</js>). * </ul> */ - String items() default ""; + String[] items() default {}; /** * Defines the swagger value <code>/paths/{path}/{method}/parameters/#/x-example</code>. @@ -383,10 +388,11 @@ public @interface Body { * <ul class='spaced-list'> * <li> * The format of the value is a JSON object or plain-text string. + * <br>Multiple lines are concatenated with newlines. * <li> * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> * (e.g. <js>"$L{my.localized.variable}"</js>). * </ul> */ - String example() default ""; + String[] example() default {}; } diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/FormData.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/FormData.java index d9c1bfa..4b7c666 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/FormData.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/FormData.java @@ -61,7 +61,7 @@ import org.apache.juneau.rest.*; * </ul> */ @Documented -@Target(PARAMETER) +@Target({PARAMETER,TYPE}) @Retention(RUNTIME) @Inherited public @interface FormData { diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/HasFormData.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/HasFormData.java index dd378d0..0bc4867 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/HasFormData.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/HasFormData.java @@ -90,7 +90,7 @@ import org.apache.juneau.rest.*; * </ul> */ @Documented -@Target(PARAMETER) +@Target({PARAMETER,TYPE}) @Retention(RUNTIME) @Inherited public @interface HasFormData { diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/HasQuery.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/HasQuery.java index a1545c9..8dfb9ba 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/HasQuery.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/HasQuery.java @@ -53,7 +53,7 @@ import org.apache.juneau.rest.*; * </ul> */ @Documented -@Target(PARAMETER) +@Target({PARAMETER,TYPE}) @Retention(RUNTIME) @Inherited public @interface HasQuery { diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Header.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Header.java index 01ad591..cc0f474 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Header.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Header.java @@ -48,7 +48,7 @@ import org.apache.juneau.rest.*; * </ul> */ @Documented -@Target(PARAMETER) +@Target({PARAMETER,TYPE}) @Retention(RUNTIME) @Inherited public @interface Header { @@ -317,7 +317,7 @@ public @interface Header { * (e.g. <js>"$L{my.localized.variable}"</js>). * </ul> */ - String exclusiveMimimum() default ""; + String exclusiveMinimum() default ""; /** * Defines the swagger value <code>/paths/{path}/{method}/parameters/#/uniqueItems</code>. diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Path.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Path.java index fa30b8e..518dd66 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Path.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Path.java @@ -75,7 +75,7 @@ import org.apache.juneau.rest.*; * </ul> */ @Documented -@Target(PARAMETER) +@Target({PARAMETER,TYPE}) @Retention(RUNTIME) @Inherited public @interface Path { diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Query.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Query.java index c3c60e7..cfb4d33 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Query.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Query.java @@ -57,7 +57,7 @@ import org.apache.juneau.rest.*; * </ul> */ @Documented -@Target(PARAMETER) +@Target({PARAMETER,TYPE}) @Retention(RUNTIME) @Inherited public @interface Query { diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/ResponseInfo.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Response.java similarity index 81% rename from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/ResponseInfo.java rename to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Response.java index 3c300b9..23a22d6 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/ResponseInfo.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Response.java @@ -24,42 +24,17 @@ import java.lang.annotation.*; @Target(TYPE) @Retention(RUNTIME) @Inherited -public @interface ResponseInfo { +public @interface Response { - /** - * The HTTP status of the response. - */ int code() default 0; - /** - * Description. - * - * <p> - * Format is plain text. - */ + int value() default 0; + String description() default ""; - /** - * Schema information. - * - * <p> - * Format is a JSON object consisting of a Swagger SchemaInfo object. - */ String[] schema() default {}; - /** - * Header information. - * - * <p> - * Format is a JSON array consisting of Swagger HeaderInfo objects. - */ String[] headers() default {}; - /** - * Example. - * - * <p> - * Format is a JSON primitive, array, or object. - */ String[] example() default {}; } diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Header.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/ResponseHeader.java similarity index 63% copy from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Header.java copy to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/ResponseHeader.java index 01ad591..abe609c 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Header.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/ResponseHeader.java @@ -1,409 +1,414 @@ -// *************************************************************************************************************************** -// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * -// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * -// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * -// * with the License. You may obtain a copy of the License at * -// * * -// * http://www.apache.org/licenses/LICENSE-2.0 * -// * * -// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * -// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * -// * specific language governing permissions and limitations under the License. * -// *************************************************************************************************************************** -package org.apache.juneau.rest.annotation; - -import static java.lang.annotation.ElementType.*; -import static java.lang.annotation.RetentionPolicy.*; - -import java.lang.annotation.*; - -import org.apache.juneau.httppart.*; -import org.apache.juneau.rest.*; - -/** - * Annotation that can be applied to a parameter of a {@link RestMethod @RestMethod} annotated method to identify it as a HTTP - * request header converted to a POJO. - * - * <h5 class='section'>Example:</h5> - * <p class='bcode'> - * <ja>@RestMethod</ja>(name=<jsf>GET</jsf>) - * <jk>public void</jk> doGet(RestRequest req, RestResponse res, <ja>@Header</ja>(<js>"ETag"</js>) UUID etag) { - * ... - * } - * </p> - * - * <p> - * This is functionally equivalent to the following code... - * <p class='bcode'> - * <ja>@RestMethod</ja>(name=<jsf>GET</jsf>) - * <jk>public void</jk> doPostPerson(RestRequest req, RestResponse res) { - * UUID etag = req.getHeader(UUID.<jk>class</jk>, "ETag"); - * ... - * } - * </p> - * - * <h5 class='section'>See Also:</h5> - * <ul> - * <li class='link'><a class="doclink" href="../../../../../overview-summary.html#juneau-rest-server.Header">Overview > juneau-rest-server > @Header</a> - * </ul> - */ -@Documented -@Target(PARAMETER) -@Retention(RUNTIME) -@Inherited -public @interface Header { - - /** - * The default value for this header if it's not present in the request. - */ - String def() default ""; - - /** - * HTTP header name. - */ - String name() default ""; - - /** - * Specifies the {@link HttpPartParser} class used for parsing values from strings. - * - * <p> - * The default value for this parser is inherited from the servlet/method which defaults to {@link UonPartParser}. - * <br>You can use {@link SimplePartParser} to parse POJOs that are directly convertible from <code>Strings</code>. - */ - Class<? extends HttpPartParser> parser() default HttpPartParser.Null.class; - - /** - * A synonym for {@link #name()}. - * - * <p> - * Allows you to use shortened notation if you're only specifying the name. - */ - String value() default ""; - - /** - * Defines the swagger value <code>/paths/{path}/{method}/parameters/#/description</code>. - * - * <h5 class='section'>Notes:</h5> - * <ul class='spaced-list'> - * <li> - * The format of the value is plain-text. - * <li> - * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> - * (e.g. <js>"$L{my.localized.variable}"</js>). - * </ul> - */ - String description() default ""; - - /** - * Defines the swagger value <code>/paths/{path}/{method}/parameters/#/required</code>. - * - * <h5 class='section'>Notes:</h5> - * <ul class='spaced-list'> - * <li> - * The format of the value is boolean. - * <li> - * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> - * (e.g. <js>"$L{my.localized.variable}"</js>). - * </ul> - */ - String required() default ""; - - /** - * Defines the swagger value <code>/paths/{path}/{method}/parameters/#/type</code>. - * - * <h5 class='section'>Notes:</h5> - * <ul class='spaced-list'> - * <li> - * The possible values are: - * <ul> - * <li><js>"string"</js> - * <li><js>"number"</js> - * <li><js>"integer"</js> - * <li><js>"boolean"</js> - * <li><js>"array"</js> - * <li><js>"file"</js> - * </ul> - * <li> - * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> - * (e.g. <js>"$L{my.localized.variable}"</js>). - * </ul> - */ - String type() default ""; - - /** - * Defines the swagger value <code>/paths/{path}/{method}/parameters/#/format</code>. - * - * <h5 class='section'>Notes:</h5> - * <ul class='spaced-list'> - * <li> - * The format of the value is plain-text: - * <li> - * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> - * (e.g. <js>"$L{my.localized.variable}"</js>). - * </ul> - */ - String format() default ""; - - /** - * Defines the swagger value <code>/paths/{path}/{method}/parameters/#/pattern</code>. - * - * <h5 class='section'>Notes:</h5> - * <ul class='spaced-list'> - * <li> - * The format of the value is plain-text. - * <li> - * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> - * (e.g. <js>"$L{my.localized.variable}"</js>). - * </ul> - */ - String pattern() default ""; - - /** - * Defines the swagger value <code>/paths/{path}/{method}/parameters/#/collectionFormat</code>. - * - * <h5 class='section'>Notes:</h5> - * <ul class='spaced-list'> - * <li> - * The possible value are: - * <ul> - * <li><js>"csv"</js> - * <li><js>"ssv"</js> - * <li><js>"tsv"</js> - * <li><js>"pipes"</js> - * <li><js>"multi"</js> - * </ul> - * <li> - * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> - * (e.g. <js>"$L{my.localized.variable}"</js>). - * </ul> - */ - String collectionFormat() default ""; - - /** - * Defines the swagger value <code>/paths/{path}/{method}/parameters/#/maximum</code>. - * - * <h5 class='section'>Notes:</h5> - * <ul class='spaced-list'> - * <li> - * The format of the value is numeric. - * <li> - * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> - * (e.g. <js>"$L{my.localized.variable}"</js>). - * </ul> - */ - String maximum() default ""; - - /** - * Defines the swagger value <code>/paths/{path}/{method}/parameters/#/minimum</code>. - * - * <h5 class='section'>Notes:</h5> - * <ul class='spaced-list'> - * <li> - * The format of the value is numeric. - * <li> - * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> - * (e.g. <js>"$L{my.localized.variable}"</js>). - * </ul> - */ - String minimum() default ""; - - /** - * Defines the swagger value <code>/paths/{path}/{method}/parameters/#/multipleOf</code>. - * - * <h5 class='section'>Notes:</h5> - * <ul class='spaced-list'> - * <li> - * The format of the value is numeric. - * <li> - * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> - * (e.g. <js>"$L{my.localized.variable}"</js>). - * </ul> - */ - String multipleOf() default ""; - - /** - * Defines the swagger value <code>/paths/{path}/{method}/parameters/#/maxLength</code>. - * - * <h5 class='section'>Notes:</h5> - * <ul class='spaced-list'> - * <li> - * The format of the value is numeric. - * <li> - * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> - * (e.g. <js>"$L{my.localized.variable}"</js>). - * </ul> - */ - String maxLength() default ""; - - /** - * Defines the swagger value <code>/paths/{path}/{method}/parameters/#/minLength</code>. - * - * <h5 class='section'>Notes:</h5> - * <ul class='spaced-list'> - * <li> - * The format of the value is numeric. - * <li> - * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> - * (e.g. <js>"$L{my.localized.variable}"</js>). - * </ul> - */ - String minLength() default ""; - - /** - * Defines the swagger value <code>/paths/{path}/{method}/parameters/#/maxItems</code>. - * - * <h5 class='section'>Notes:</h5> - * <ul class='spaced-list'> - * <li> - * The format of the value is numeric. - * <li> - * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> - * (e.g. <js>"$L{my.localized.variable}"</js>). - * </ul> - */ - String maxItems() default ""; - - /** - * Defines the swagger value <code>/paths/{path}/{method}/parameters/#/minItems</code>. - * - * <h5 class='section'>Notes:</h5> - * <ul class='spaced-list'> - * <li> - * The format of the value is numeric. - * <li> - * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> - * (e.g. <js>"$L{my.localized.variable}"</js>). - * </ul> - */ - String minItems() default ""; - - /** - * Defines the swagger value <code>/paths/{path}/{method}/parameters/#/allowEmptyVals</code>. - * - * <h5 class='section'>Notes:</h5> - * <ul class='spaced-list'> - * <li> - * The format of the value is boolean. - * <li> - * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> - * (e.g. <js>"$L{my.localized.variable}"</js>). - * </ul> - */ - String allowEmptyVals() default ""; - - /** - * Defines the swagger value <code>/paths/{path}/{method}/parameters/#/exclusiveMaximum</code>. - * - * <h5 class='section'>Notes:</h5> - * <ul class='spaced-list'> - * <li> - * The format of the value is numeric. - * <li> - * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> - * (e.g. <js>"$L{my.localized.variable}"</js>). - * </ul> - */ - String exclusiveMaximum() default ""; - - /** - * Defines the swagger value <code>/paths/{path}/{method}/parameters/#/exclusiveMimimum</code>. - * - * <h5 class='section'>Notes:</h5> - * <ul class='spaced-list'> - * <li> - * The format of the value is numeric. - * <li> - * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> - * (e.g. <js>"$L{my.localized.variable}"</js>). - * </ul> - */ - String exclusiveMimimum() default ""; - - /** - * Defines the swagger value <code>/paths/{path}/{method}/parameters/#/uniqueItems</code>. - * - * <h5 class='section'>Notes:</h5> - * <ul class='spaced-list'> - * <li> - * The format of the value is boolean. - * <li> - * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> - * (e.g. <js>"$L{my.localized.variable}"</js>). - * </ul> - */ - String uniqueItems() default ""; - - /** - * Defines the swagger value <code>/paths/{path}/{method}/parameters/#/schema</code>. - * - * <h5 class='section'>Notes:</h5> - * <ul class='spaced-list'> - * <li> - * The format of the value is a JSON object. - * <li> - * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> - * (e.g. <js>"$L{my.localized.variable}"</js>). - * </ul> - */ - String schema() default ""; - - /** - * Defines the swagger value <code>/paths/{path}/{method}/parameters/#/default</code>. - * - * <h5 class='section'>Notes:</h5> - * <ul class='spaced-list'> - * <li> - * The format of the value is JSON. - * <li> - * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> - * (e.g. <js>"$L{my.localized.variable}"</js>). - * </ul> - */ - String _default() default ""; - - /** - * Defines the swagger value <code>/paths/{path}/{method}/parameters/#/enum</code>. - * - * <h5 class='section'>Notes:</h5> - * <ul class='spaced-list'> - * <li> - * The format of the value is a JSON array or comma-delimited list. - * <li> - * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> - * (e.g. <js>"$L{my.localized.variable}"</js>). - * </ul> - */ - String _enum() default ""; - - /** - * Defines the swagger value <code>/paths/{path}/{method}/parameters/#/items</code>. - * - * <h5 class='section'>Notes:</h5> - * <ul class='spaced-list'> - * <li> - * The format of the value is a JSON object. - * <li> - * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> - * (e.g. <js>"$L{my.localized.variable}"</js>). - * </ul> - */ - String items() default ""; - - /** - * Defines the swagger value <code>/paths/{path}/{method}/parameters/#/x-example</code>. - * - * <p> - * This attribute defines a JSON representation of the value that is used by {@link BasicRestInfoProvider} to construct - * an example of the header entry. - * - * <h5 class='section'>Notes:</h5> - * <ul class='spaced-list'> - * <li> - * The format of the value is a JSON object or plain-text string. - * <li> - * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> - * (e.g. <js>"$L{my.localized.variable}"</js>). - * </ul> - */ - String example() default ""; -} +// *************************************************************************************************************************** +// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * +// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * +// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * +// * with the License. You may obtain a copy of the License at * +// * * +// * http://www.apache.org/licenses/LICENSE-2.0 * +// * * +// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * +// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * +// * specific language governing permissions and limitations under the License. * +// *************************************************************************************************************************** +package org.apache.juneau.rest.annotation; + +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.*; + +import java.lang.annotation.*; + +import org.apache.juneau.httppart.*; +import org.apache.juneau.rest.*; +import org.apache.juneau.utils.*; + +/** + * Annotation that can be applied to parameters and types to denote them as an HTTP response headers. + * + * <p> + * This annotation can only be applied to subclasses of type {@link Value}. + * + * <p> + * The following examples show 3 different ways of accomplishing the same task of setting an HTTP header + * on a response: + * + * <p class='bcode'> + * <jc>// Example #1 - Setting header directly on RestResponse object.</jc> + * <ja>@RestMethod</ja>(...) + * <jk>public void</jk> login(RestResponse res) { + * res.setHeader(<js>"X-Rate-Limit"</js>, 1000); + * ... + * } + * + * <jc>// Example #2 - Use on parameter.</jc> + * <ja>@RestMethod</ja>(...) + * <jk>public void</jk> login( + * <ja>@ResponseHeader</ja>(name=<js>"X-Rate-Limit"</js>, type=<js>"integer"</js>, format=<js>"int32"</js>, description=<js>"Calls per hour allowed by the user."</js>, example=<js>"123"</js>) + * Value<Integer> rateLimit + * ) { + * rateLimit.set(1000); + * ... + * } + * + * <jc>// Example #3 - Use on type.</jc> + * <ja>@RestMethod</ja>(...) + * <jk>public void</jk> login(RateLimit rateLimit) { + * rateLimit.set(1000); + * ... + * } + * + * <ja>@ResponseHeader</ja>(name=<js>"X-Rate-Limit"</js>, type=<js>"integer"</js>, format=<js>"int32"</js>, description=<js>"Calls per hour allowed by the user."</js>, example=<js>"123"</js>) + * <jk>public static class</jk> RateLimit <jk>extends</jk> Value<Integer> {} + * </p> + */ +@Documented +@Target({PARAMETER,TYPE}) +@Retention(RUNTIME) +@Inherited +public @interface ResponseHeader { + + /** + * The HTTP status (or statuses) of the response. + * + * <h5 class='section'>Notes:</h5> + * <ul class='spaced-list'> + * <li> + * The format of the value is a comma-delimited list of HTTP status codes that this header applies to. + * <li> + * The default value is <js>"200"</js>. + * </ul> + */ + String code() default ""; + + /** + * The HTTP header name. + * + * <h5 class='section'>Notes:</h5> + * <ul class='spaced-list'> + * <li> + * At least one of {@link #name()} or {@link #value()} must be specified}. + * </ul> + */ + String name() default ""; + + /** + * A synonym to {@link #name()}. + * + * <p> + * Useful if you only want to specify a header name. + * + * <p class='bcode'> + * <ja>@RestMethod</ja>(...) + * <jk>public void</jk> login(<ja>@ResponseHeader</ja>(<js>"X-Rate-Limit"</js>) Value<Integer> rateLimit) { + * rateLimit.set(1000); + * ... + * } + * </p> + * + * <h5 class='section'>Notes:</h5> + * <ul class='spaced-list'> + * <li> + * At least one of {@link #name()} or {@link #value()} must be specified}. + * </ul> + */ + String value() default ""; + + /** + * Specifies the {@link HttpPartSerializer} class used for serializing values. + * + * <p> + * The default value for this parser is inherited from the servlet/method which defaults to {@link SimpleUonPartSerializer}. + */ + Class<? extends HttpPartSerializer> serializer() default HttpPartSerializer.Null.class; + + /** + * Defines the swagger value <code>/paths/{path}/{method}/responses/{status-code}/headers/{header-name}/description</code>. + * + * <h5 class='section'>Notes:</h5> + * <ul class='spaced-list'> + * <li> + * The format of the value is plain-text. + * <br>Multiple lines are concatenated with newlines. + * <li> + * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> + * (e.g. <js>"$L{my.localized.variable}"</js>). + * </ul> + */ + String[] description() default {}; + + /** + * Defines the swagger value <code>/paths/{path}/{method}/responses/{status-code}/headers/{header-name}/type</code>. + * + * <h5 class='section'>Notes:</h5> + * <ul class='spaced-list'> + * <li> + * The possible values are: + * <ul> + * <li><js>"string"</js> + * <li><js>"number"</js> + * <li><js>"integer"</js> + * <li><js>"boolean"</js> + * <li><js>"array"</js> + * </ul> + * <li> + * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> + * (e.g. <js>"$L{my.localized.variable}"</js>). + * </ul> + */ + String type() default ""; + + /** + * Defines the swagger value <code>/paths/{path}/{method}/responses/{status-code}/headers/{header-name}/format</code>. + * + * <h5 class='section'>Notes:</h5> + * <ul class='spaced-list'> + * <li> + * The format of the value is plain-text: + * <li> + * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> + * (e.g. <js>"$L{my.localized.variable}"</js>). + * </ul> + */ + String format() default ""; + + /** + * Defines the swagger value <code>/paths/{path}/{method}/responses/{status-code}/headers/{header-name}/collectionFormat</code>. + * + * <h5 class='section'>Notes:</h5> + * <ul class='spaced-list'> + * <li> + * The possible value are: + * <ul> + * <li><js>"csv"</js> + * <li><js>"ssv"</js> + * <li><js>"tsv"</js> + * <li><js>"pipes"</js> + * <li><js>"multi"</js> + * </ul> + * <li> + * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> + * (e.g. <js>"$L{my.localized.variable}"</js>). + * </ul> + */ + String collectionFormat() default ""; + + /** + * Defines the swagger value <code>/paths/{path}/{method}/responses/{status-code}/headers/{header-name}/$ref</code>. + * + * <p> + * Denotes a reference to a definition object. + * + * <h5 class='section'>Notes:</h5> + * <ul class='spaced-list'> + * <li> + * The format of the value is plain-text: + * <li> + * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> + * (e.g. <js>"$L{my.localized.variable}"</js>). + * </ul> + */ + String $ref() default ""; + + /** + * Defines the swagger value <code>/paths/{path}/{method}/responses/{status-code}/headers/{header-name}/maximum</code>. + * + * <h5 class='section'>Notes:</h5> + * <ul class='spaced-list'> + * <li> + * The format of the value is numeric. + * <li> + * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> + * (e.g. <js>"$L{my.localized.variable}"</js>). + * </ul> + */ + String maximum() default ""; + + /** + * Defines the swagger value <code>/paths/{path}/{method}/responses/{status-code}/headers/{header-name}/minimum</code>. + * + * <h5 class='section'>Notes:</h5> + * <ul class='spaced-list'> + * <li> + * The format of the value is numeric. + * <li> + * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> + * (e.g. <js>"$L{my.localized.variable}"</js>). + * </ul> + */ + String minimum() default ""; + + /** + * Defines the swagger value <code>/paths/{path}/{method}/responses/{status-code}/headers/{header-name}/multipleOf</code>. + * + * <h5 class='section'>Notes:</h5> + * <ul class='spaced-list'> + * <li> + * The format of the value is numeric. + * <li> + * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> + * (e.g. <js>"$L{my.localized.variable}"</js>). + * </ul> + */ + String multipleOf() default ""; + + /** + * Defines the swagger value <code>/paths/{path}/{method}/responses/{status-code}/headers/{header-name}/maxLength</code>. + * + * <h5 class='section'>Notes:</h5> + * <ul class='spaced-list'> + * <li> + * The format of the value is numeric. + * <li> + * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> + * (e.g. <js>"$L{my.localized.variable}"</js>). + * </ul> + */ + String maxLength() default ""; + + /** + * Defines the swagger value <code>/paths/{path}/{method}/responses/{status-code}/headers/{header-name}/minLength</code>. + * + * <h5 class='section'>Notes:</h5> + * <ul class='spaced-list'> + * <li> + * The format of the value is numeric. + * <li> + * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> + * (e.g. <js>"$L{my.localized.variable}"</js>). + * </ul> + */ + String minLength() default ""; + + /** + * Defines the swagger value <code>/paths/{path}/{method}/responses/{status-code}/headers/{header-name}/maxItems</code>. + * + * <h5 class='section'>Notes:</h5> + * <ul class='spaced-list'> + * <li> + * The format of the value is numeric. + * <li> + * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> + * (e.g. <js>"$L{my.localized.variable}"</js>). + * </ul> + */ + String maxItems() default ""; + + /** + * Defines the swagger value <code>/paths/{path}/{method}/responses/{status-code}/headers/{header-name}/minItems</code>. + * + * <h5 class='section'>Notes:</h5> + * <ul class='spaced-list'> + * <li> + * The format of the value is numeric. + * <li> + * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> + * (e.g. <js>"$L{my.localized.variable}"</js>). + * </ul> + */ + String minItems() default ""; + + /** + * Defines the swagger value <code>/paths/{path}/{method}/responses/{status-code}/headers/{header-name}/exclusiveMaximum</code>. + * + * <h5 class='section'>Notes:</h5> + * <ul class='spaced-list'> + * <li> + * The format of the value is numeric. + * <li> + * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> + * (e.g. <js>"$L{my.localized.variable}"</js>). + * </ul> + */ + String exclusiveMaximum() default ""; + + /** + * Defines the swagger value <code>/paths/{path}/{method}/responses/{status-code}/headers/{header-name}/exclusiveMimimum</code>. + * + * <h5 class='section'>Notes:</h5> + * <ul class='spaced-list'> + * <li> + * The format of the value is numeric. + * <li> + * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> + * (e.g. <js>"$L{my.localized.variable}"</js>). + * </ul> + */ + String exclusiveMinimum() default ""; + + /** + * Defines the swagger value <code>/paths/{path}/{method}/responses/{status-code}/headers/{header-name}/uniqueItems</code>. + * + * <h5 class='section'>Notes:</h5> + * <ul class='spaced-list'> + * <li> + * The format of the value is boolean. + * <li> + * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> + * (e.g. <js>"$L{my.localized.variable}"</js>). + * </ul> + */ + String uniqueItems() default ""; + + /** + * Defines the swagger value <code>/paths/{path}/{method}/responses/{status-code}/headers/{header-name}/items</code>. + * + * <h5 class='section'>Notes:</h5> + * <ul class='spaced-list'> + * <li> + * The format of the value is a JSON object. + * <br>Multiple lines are concatenated with newlines. + * <li> + * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> + * (e.g. <js>"$L{my.localized.variable}"</js>). + * </ul> + */ + String[] items() default {}; + + /** + * Defines the swagger value <code>/paths/{path}/{method}/responses/{status-code}/headers/{header-name}/default</code>. + * + * <h5 class='section'>Notes:</h5> + * <ul class='spaced-list'> + * <li> + * The format of the value is JSON. + * <br>Multiple lines are concatenated with newlines. + * <li> + * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> + * (e.g. <js>"$L{my.localized.variable}"</js>). + * </ul> + */ + String[] _default() default {}; + + /** + * Defines the swagger value <code>/paths/{path}/{method}/responses/{status-code}/headers/{header-name}/enum</code>. + * + * <h5 class='section'>Notes:</h5> + * <ul class='spaced-list'> + * <li> + * The format of the value is a JSON array or comma-delimited list. + * <br>Multiple lines are concatenated with newlines. + * <li> + * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> + * (e.g. <js>"$L{my.localized.variable}"</js>). + * </ul> + */ + String[] _enum() default {}; + + /** + * Defines the swagger value <code>/paths/{path}/{method}/responses/{status-code}/headers/{header-name}/x-example</code>. + * + * <p> + * This attribute defines a JSON representation of the body value that is used by {@link BasicRestInfoProvider} to construct + * media-type-based examples of the header value. + * + * <h5 class='section'>Notes:</h5> + * <ul class='spaced-list'> + * <li> + * The format of the value is a JSON object or plain-text string. + * <br>Multiple lines are concatenated with newlines. + * <li> + * Supports <a class="doclink" href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time and request-time variables</a> + * (e.g. <js>"$L{my.localized.variable}"</js>). + * </ul> + */ + String[] example() default {}; +} diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/helper/RedirectToServletRoot.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/ResponseStatus.java similarity index 75% copy from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/helper/RedirectToServletRoot.java copy to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/ResponseStatus.java index b1acdeb..6413740 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/helper/RedirectToServletRoot.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/ResponseStatus.java @@ -10,25 +10,28 @@ // * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * // * specific language governing permissions and limitations under the License. * // *************************************************************************************************************************** -package org.apache.juneau.rest.helper; +package org.apache.juneau.rest.annotation; -import org.apache.juneau.rest.annotation.*; +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.*; + +import java.lang.annotation.*; /** - * Convenience subclass of {@link Redirect} for redirecting a response to the servlet root. + * Annotation that can be applied to parameters and types to denote them as an HTTP response status. */ -@ResponseInfo(description="Redirect to servlet root") -public class RedirectToServletRoot extends Redirect { +@Documented +@Target({PARAMETER,TYPE}) +@Retention(RUNTIME) +@Inherited +public @interface ResponseStatus { /** - * Reusable instance. + * The HTTP status of the response. */ - public static final RedirectToServletRoot INSTANCE = new RedirectToServletRoot(); + int code() default 0; - /** - * Constructor. - */ - public RedirectToServletRoot() { - super("servlet:/"); - } -} \ No newline at end of file + int value() default 0; + + String[] description() default {}; +} diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/InvalidSpecies.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/ResponseStatuses.java similarity index 74% copy from juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/InvalidSpecies.java copy to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/ResponseStatuses.java index d856988..d5bbee4 100644 --- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/InvalidSpecies.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/ResponseStatuses.java @@ -1,31 +1,27 @@ -// *************************************************************************************************************************** -// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * -// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * -// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * -// * with the License. You may obtain a copy of the License at * -// * * -// * http://www.apache.org/licenses/LICENSE-2.0 * -// * * -// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * -// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * -// * specific language governing permissions and limitations under the License. * -// *************************************************************************************************************************** -package org.apache.juneau.examples.rest.petstore; - -import org.apache.juneau.rest.annotation.*; -import org.apache.juneau.rest.exception.*; - -/** - * Exception thrown when an invalid species is looked up. - */ -@SuppressWarnings("serial") -@ResponseInfo(description="Invalid species provided") -public class InvalidSpecies extends BadRequest { - - /** - * Constructor. - */ - public InvalidSpecies() { - super("Invalid species provided."); - } -} +// *************************************************************************************************************************** +// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * +// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * +// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * +// * with the License. You may obtain a copy of the License at * +// * * +// * http://www.apache.org/licenses/LICENSE-2.0 * +// * * +// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * +// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * +// * specific language governing permissions and limitations under the License. * +// *************************************************************************************************************************** +package org.apache.juneau.rest.annotation; + +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.*; + +import java.lang.annotation.*; + +@Documented +@Target({TYPE}) +@Retention(RUNTIME) +@Inherited +public @interface ResponseStatuses { + + ResponseStatus[] value() default {}; +} \ No newline at end of file diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/InvalidSpecies.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Responses.java similarity index 74% copy from juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/InvalidSpecies.java copy to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Responses.java index d856988..b8c7870 100644 --- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/petstore/InvalidSpecies.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Responses.java @@ -1,31 +1,27 @@ -// *************************************************************************************************************************** -// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * -// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * -// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * -// * with the License. You may obtain a copy of the License at * -// * * -// * http://www.apache.org/licenses/LICENSE-2.0 * -// * * -// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * -// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * -// * specific language governing permissions and limitations under the License. * -// *************************************************************************************************************************** -package org.apache.juneau.examples.rest.petstore; - -import org.apache.juneau.rest.annotation.*; -import org.apache.juneau.rest.exception.*; - -/** - * Exception thrown when an invalid species is looked up. - */ -@SuppressWarnings("serial") -@ResponseInfo(description="Invalid species provided") -public class InvalidSpecies extends BadRequest { - - /** - * Constructor. - */ - public InvalidSpecies() { - super("Invalid species provided."); - } -} +// *************************************************************************************************************************** +// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * +// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * +// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * +// * with the License. You may obtain a copy of the License at * +// * * +// * http://www.apache.org/licenses/LICENSE-2.0 * +// * * +// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * +// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * +// * specific language governing permissions and limitations under the License. * +// *************************************************************************************************************************** +package org.apache.juneau.rest.annotation; + +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.*; + +import java.lang.annotation.*; + +@Documented +@Target({TYPE}) +@Retention(RUNTIME) +@Inherited +public @interface Responses { + + Response[] value() default {}; +} \ No newline at end of file diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/BadRequest.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/BadRequest.java index 0c2a0c1..8416498 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/BadRequest.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/BadRequest.java @@ -25,7 +25,7 @@ import org.apache.juneau.rest.annotation.*; * <p> * The server cannot or will not process the request due to an apparent client error (e.g., malformed request syntax, size too large, invalid request message framing, or deceptive request routing). */ -@ResponseInfo( +@Response( code=CODE, description=MESSAGE ) diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/Conflict.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/Conflict.java index 2fc9528..3a202e8 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/Conflict.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/Conflict.java @@ -25,7 +25,7 @@ import org.apache.juneau.rest.annotation.*; * <p> * Indicates that the request could not be processed because of conflict in the request, such as an edit conflict between multiple simultaneous updates. */ -@ResponseInfo( +@Response( code=CODE, description=MESSAGE ) diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/ExpectationFailed.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/ExpectationFailed.java index ba5f1f0..49b9e69 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/ExpectationFailed.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/ExpectationFailed.java @@ -25,7 +25,7 @@ import org.apache.juneau.rest.annotation.*; * <p> * The server cannot meet the requirements of the Expect request-header field. */ -@ResponseInfo( +@Response( code=CODE, description=MESSAGE ) diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/FailedDependency.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/FailedDependency.java index 97242a7..32f9109 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/FailedDependency.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/FailedDependency.java @@ -25,7 +25,7 @@ import org.apache.juneau.rest.annotation.*; * <p> * The request failed because it depended on another request and that request failed (e.g., a PROPPATCH). */ -@ResponseInfo( +@Response( code=CODE, description=MESSAGE ) diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/Forbidden.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/Forbidden.java index d019699..bfab8f0 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/Forbidden.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/Forbidden.java @@ -26,7 +26,7 @@ import org.apache.juneau.rest.annotation.*; * The request was valid, but the server is refusing action. * <br>The user might not have the necessary permissions for a resource, or may need an account of some sort. */ -@ResponseInfo( +@Response( code=CODE, description=MESSAGE ) diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/Gone.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/Gone.java index beca699..254c615 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/Gone.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/Gone.java @@ -29,7 +29,7 @@ import org.apache.juneau.rest.annotation.*; * <br>Clients such as search engines should remove the resource from their indices. * <br>Most use cases do not require clients and search engines to purge the resource, and a <js>"404 Not Found"</js> may be used instead. */ -@ResponseInfo( +@Response( code=CODE, description=MESSAGE ) diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/HttpVersionNotSupported.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/HttpVersionNotSupported.java index 31c4319..c735643 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/HttpVersionNotSupported.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/HttpVersionNotSupported.java @@ -25,7 +25,7 @@ import org.apache.juneau.rest.annotation.*; * <p> * The server does not support the HTTP protocol version used in the request. */ -@ResponseInfo( +@Response( code=CODE, description=MESSAGE ) diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/InsufficientStorage.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/InsufficientStorage.java index fd919ef..8e20322 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/InsufficientStorage.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/InsufficientStorage.java @@ -25,7 +25,7 @@ import org.apache.juneau.rest.annotation.*; * <p> * The server is unable to store the representation needed to complete the request. */ -@ResponseInfo( +@Response( code=CODE, description=MESSAGE ) diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/InternalServerError.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/InternalServerError.java index 9d53925..a530016 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/InternalServerError.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/InternalServerError.java @@ -25,7 +25,7 @@ import org.apache.juneau.rest.annotation.*; * <p> * A generic error message, given when an unexpected condition was encountered and no more specific message is suitable. */ -@ResponseInfo( +@Response( code=CODE, description=MESSAGE ) diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/LengthRequired.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/LengthRequired.java index be37718..fa2d5d8 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/LengthRequired.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/LengthRequired.java @@ -25,7 +25,7 @@ import org.apache.juneau.rest.annotation.*; * <p> * The request did not specify the length of its content, which is required by the requested resource. */ -@ResponseInfo( +@Response( code=CODE, description=MESSAGE ) diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/Locked.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/Locked.java index 65df3d3..2d1403d 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/Locked.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/Locked.java @@ -25,7 +25,7 @@ import org.apache.juneau.rest.annotation.*; * <p> * The resource that is being accessed is locked. */ -@ResponseInfo( +@Response( code=CODE, description=MESSAGE ) diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/LoopDetected.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/LoopDetected.java index 2f0c88d..2a61ebb 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/LoopDetected.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/LoopDetected.java @@ -25,7 +25,7 @@ import org.apache.juneau.rest.annotation.*; * <p> * The server detected an infinite loop while processing the request (sent in lieu of 208 Already Reported). */ -@ResponseInfo( +@Response( code=CODE, description=MESSAGE ) diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/MethodNotAllowed.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/MethodNotAllowed.java index f3c54f4..0415f64 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/MethodNotAllowed.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/MethodNotAllowed.java @@ -25,7 +25,7 @@ import org.apache.juneau.rest.annotation.*; * <p> * A request method is not supported for the requested resource; for example, a GET request on a form that requires data to be presented via POST, or a PUT request on a read-only resource. */ -@ResponseInfo( +@Response( code=CODE, description=MESSAGE ) diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/MisdirectedRequest.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/MisdirectedRequest.java index 174a3c6..2531134 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/MisdirectedRequest.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/MisdirectedRequest.java @@ -25,7 +25,7 @@ import org.apache.juneau.rest.annotation.*; * <p> * The request was directed at a server that is not able to produce a response (for example because of connection reuse). */ -@ResponseInfo( +@Response( code=CODE, description=MESSAGE ) diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/NetworkAuthenticationRequired.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/NetworkAuthenticationRequired.java index cd1a77a..0437013 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/NetworkAuthenticationRequired.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/NetworkAuthenticationRequired.java @@ -26,7 +26,7 @@ import org.apache.juneau.rest.annotation.*; * The client needs to authenticate to gain network access. * <br>Intended for use by intercepting proxies used to control access to the network (e.g., "captive portals" used to require agreement to Terms of Service before granting full Internet access via a Wi-Fi hotspot). */ -@ResponseInfo( +@Response( code=CODE, description=MESSAGE ) diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/NotAcceptable.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/NotAcceptable.java index 44dd802..11652e9 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/NotAcceptable.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/NotAcceptable.java @@ -25,7 +25,7 @@ import org.apache.juneau.rest.annotation.*; * <br> * The requested resource is capable of generating only content not acceptable according to the Accept headers sent in the request. */ -@ResponseInfo( +@Response( code=CODE, description=MESSAGE ) diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/NotExtended.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/NotExtended.java index 834f609..58f0e0a 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/NotExtended.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/NotExtended.java @@ -25,7 +25,7 @@ import org.apache.juneau.rest.annotation.*; * <p> * Further extensions to the request are required for the server to fulfill it. */ -@ResponseInfo( +@Response( code=CODE, description=MESSAGE ) diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/NotFound.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/NotFound.java index 42aefab..fb551fb 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/NotFound.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/NotFound.java @@ -26,7 +26,7 @@ import org.apache.juneau.rest.annotation.*; * The requested resource could not be found but may be available in the future. * <br>Subsequent requests by the client are permissible. */ -@ResponseInfo( +@Response( code=CODE, description=MESSAGE ) diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/NotImplemented.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/NotImplemented.java index 184d117..342fa22 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/NotImplemented.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/NotImplemented.java @@ -26,7 +26,7 @@ import org.apache.juneau.rest.annotation.*; * The server either does not recognize the request method, or it lacks the ability to fulfill the request. * <br>Usually this implies future availability (e.g., a new feature of a web-service API). */ -@ResponseInfo( +@Response( code=CODE, description=MESSAGE ) diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/PayloadTooLarge.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/PayloadTooLarge.java index 90f5855..2e9d0ad 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/PayloadTooLarge.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/PayloadTooLarge.java @@ -25,7 +25,7 @@ import org.apache.juneau.rest.annotation.*; * <p> * The request is larger than the server is willing or able to process. */ -@ResponseInfo( +@Response( code=CODE, description=MESSAGE ) diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/PreconditionFailed.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/PreconditionFailed.java index a9e806c..3e39ae1 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/PreconditionFailed.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/PreconditionFailed.java @@ -25,7 +25,7 @@ import org.apache.juneau.rest.annotation.*; * <p> * The server does not meet one of the preconditions that the requester put on the request. */ -@ResponseInfo( +@Response( code=CODE, description=MESSAGE ) diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/PreconditionRequired.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/PreconditionRequired.java index 00f90df..c66222e 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/PreconditionRequired.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/PreconditionRequired.java @@ -26,7 +26,7 @@ import org.apache.juneau.rest.annotation.*; * The origin server requires the request to be conditional. * <br>Intended to prevent the 'lost update' problem, where a client GETs a resource's state, modifies it, and PUTs it back to the server, when meanwhile a third party has modified the state on the server, leading to a conflict. */ -@ResponseInfo( +@Response( code=CODE, description=MESSAGE ) diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/RangeNotSatisfiable.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/RangeNotSatisfiable.java index 953fdef..49ff505 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/RangeNotSatisfiable.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/RangeNotSatisfiable.java @@ -26,7 +26,7 @@ import org.apache.juneau.rest.annotation.*; * The client has asked for a portion of the file (byte serving), but the server cannot supply that portion. * <br>For example, if the client asked for a part of the file that lies beyond the end of the file. */ -@ResponseInfo( +@Response( code=CODE, description=MESSAGE ) diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/RequestHeaderFieldsTooLarge.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/RequestHeaderFieldsTooLarge.java index 398a63c..9a83dbf 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/RequestHeaderFieldsTooLarge.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/RequestHeaderFieldsTooLarge.java @@ -25,7 +25,7 @@ import org.apache.juneau.rest.annotation.*; * <p> * The server is unwilling to process the request because either an individual header field, or all the header fields collectively, are too large. */ -@ResponseInfo( +@Response( code=CODE, description=MESSAGE ) diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/ServiceUnavailable.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/ServiceUnavailable.java index 2628e37..5e80977 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/ServiceUnavailable.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/ServiceUnavailable.java @@ -26,7 +26,7 @@ import org.apache.juneau.rest.annotation.*; * The server is currently unavailable (because it is overloaded or down for maintenance). * <br>Generally, this is a temporary state. */ -@ResponseInfo( +@Response( code=CODE, description=MESSAGE ) diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/TooManyRequests.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/TooManyRequests.java index 275067c..3dff3b1 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/TooManyRequests.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/TooManyRequests.java @@ -26,7 +26,7 @@ import org.apache.juneau.rest.annotation.*; * The user has sent too many requests in a given amount of time. * <br>Intended for use with rate-limiting schemes. */ -@ResponseInfo( +@Response( code=CODE, description=MESSAGE ) diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/Unauthorized.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/Unauthorized.java index fecbc8a..49f27f6 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/Unauthorized.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/Unauthorized.java @@ -28,7 +28,7 @@ import org.apache.juneau.rest.annotation.*; * <br>401 semantically means "unauthenticated",i.e. the user does not have the necessary credentials. * <br>Note: Some sites issue HTTP 401 when an IP address is banned from the website (usually the website domain) and that specific address is refused permission to access a website. */ -@ResponseInfo( +@Response( code=CODE, description=MESSAGE ) diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/UnavailableForLegalReasons.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/UnavailableForLegalReasons.java index d84de7e..5b2f6dc 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/UnavailableForLegalReasons.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/UnavailableForLegalReasons.java @@ -25,7 +25,7 @@ import org.apache.juneau.rest.annotation.*; * <p> * A server operator has received a legal demand to deny access to a resource or to a set of resources that includes the requested resource. */ -@ResponseInfo( +@Response( code=CODE, description=MESSAGE ) diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/UnprocessableEntity.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/UnprocessableEntity.java index 8e81565..635e6a3 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/UnprocessableEntity.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/UnprocessableEntity.java @@ -25,7 +25,7 @@ import org.apache.juneau.rest.annotation.*; * <p> * The request was well-formed but was unable to be followed due to semantic errors. */ -@ResponseInfo( +@Response( code=CODE, description=MESSAGE ) diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/UnsupportedMediaType.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/UnsupportedMediaType.java index 2074e5c..c5c29e8 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/UnsupportedMediaType.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/UnsupportedMediaType.java @@ -26,7 +26,7 @@ import org.apache.juneau.rest.annotation.*; * The request entity has a media type which the server or resource does not support. * <br>For example, the client uploads an image as image/svg+xml, but the server requires that images use a different format. */ -@ResponseInfo( +@Response( code=CODE, description=MESSAGE ) diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/UpgradeRequired.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/UpgradeRequired.java index b047ab8..5f84ea4 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/UpgradeRequired.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/UpgradeRequired.java @@ -25,7 +25,7 @@ import org.apache.juneau.rest.annotation.*; * <p> * The client should switch to a different protocol such as TLS/1.0, given in the Upgrade header field. */ -@ResponseInfo( +@Response( code=CODE, description=MESSAGE ) diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/UriTooLong.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/UriTooLong.java index 5edee8b..fad2e41 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/UriTooLong.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/UriTooLong.java @@ -26,7 +26,7 @@ import org.apache.juneau.rest.annotation.*; * The URI provided was too long for the server to process. * <br>Often the result of too much data being encoded as a query-string of a GET request, in which case it should be converted to a POST request. */ -@ResponseInfo( +@Response( code=CODE, description=MESSAGE ) diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/VariantAlsoNegotiates.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/VariantAlsoNegotiates.java index d413cd8..cde7b29 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/VariantAlsoNegotiates.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/exception/VariantAlsoNegotiates.java @@ -25,7 +25,7 @@ import org.apache.juneau.rest.annotation.*; * <p> * Transparent content negotiation for the request results in a circular reference. */ -@ResponseInfo( +@Response( code=CODE, description=MESSAGE ) diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/helper/Ok.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/helper/Ok.java index 99c7d85..2bb09a8 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/helper/Ok.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/helper/Ok.java @@ -20,7 +20,7 @@ import org.apache.juneau.rest.annotation.*; * <p> * The response consist of the serialized string <js>"OK"</js>. */ -@ResponseInfo(code=200, example="'OK'") +@Response(code=200, example="'OK'") public class Ok { /** diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/helper/Redirect.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/helper/Redirect.java index 3dcd402..6495b72 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/helper/Redirect.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/helper/Redirect.java @@ -27,7 +27,7 @@ import org.apache.juneau.rest.annotation.*; * <li class='link'><a class="doclink" href="../../../../overview-summary.html#juneau-rest-server.Redirect">Overview > juneau-rest-server > Redirect</a> * </ul> */ -@ResponseInfo(code=302, description="Redirect", headers={"Location:{description:'Redirect URI', type:'string', format:'uri'}"}, schema="IGNORE") +@Response(code=302, description="Redirect", headers={"Location:{description:'Redirect URI', type:'string', format:'uri'}"}, schema="IGNORE") public class Redirect { private final int httpResponseCode; diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/helper/RedirectToServletRoot.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/helper/RedirectToServletRoot.java index b1acdeb..3c721e1 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/helper/RedirectToServletRoot.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/helper/RedirectToServletRoot.java @@ -17,7 +17,7 @@ import org.apache.juneau.rest.annotation.*; /** * Convenience subclass of {@link Redirect} for redirecting a response to the servlet root. */ -@ResponseInfo(description="Redirect to servlet root") +@Response(description="Redirect to servlet root") public class RedirectToServletRoot extends Redirect { /** diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/helper/ResourceDescription.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/helper/ResourceDescription.java index d419358..732e506 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/helper/ResourceDescription.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/helper/ResourceDescription.java @@ -30,7 +30,7 @@ import org.apache.juneau.rest.annotation.*; * </ul> */ @Bean(properties="name,description", fluentSetters=true) -@ResponseInfo(schema="IGNORE") +@Response(schema="IGNORE") public final class ResourceDescription implements Comparable<ResourceDescription> { private String name, description; -- To stop receiving notification emails like this one, please contact jamesbog...@apache.org.