All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.juneau.httppart.bean.ResponseBeanMeta Maven / Gradle / Ivy

// ***************************************************************************************************************************
// * 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.httppart.bean;

import static org.apache.juneau.httppart.bean.Utils.*;
import static org.apache.juneau.internal.ClassUtils.*;
import static org.apache.juneau.internal.CollectionUtils.*;
import static org.apache.juneau.httppart.HttpPartType.*;
import static org.apache.juneau.annotation.InvalidAnnotationException.*;

import java.io.*;
import java.lang.reflect.*;
import java.util.*;

import org.apache.juneau.*;
import org.apache.juneau.http.annotation.*;
import org.apache.juneau.httppart.*;
import org.apache.juneau.internal.*;
import org.apache.juneau.reflect.*;

/**
 * Represents the metadata gathered from a parameter or class annotated with {@link Response}.
 *
 * 
See Also:
*/ public class ResponseBeanMeta { /** * Represents a non-existent meta object. */ public static ResponseBeanMeta NULL = new ResponseBeanMeta(new Builder(AnnotationWorkList.create())); /** * Create metadata from specified class. * * @param t The class annotated with {@link Response}. * @param annotations The annotations to apply to any new part serializers or parsers. * @return Metadata about the class, or null if class not annotated with {@link Response}. */ public static ResponseBeanMeta create(Type t, AnnotationWorkList annotations) { ClassInfo ci = ClassInfo.of(t).unwrap(Value.class, Optional.class); if (ci.hasNoAnnotation(Response.class)) return null; Builder b = new Builder(annotations); b.apply(ci.innerType()); ci.forEachAnnotation(Response.class, x -> true, x -> b.apply(x)); ci.forEachAnnotation(StatusCode.class, x -> true, x -> b.apply(x)); return b.build(); } /** * Create metadata from specified method return. * * @param m The method annotated with {@link Response}. * @param annotations The annotations to apply to any new part serializers or parsers. * @return Metadata about the class, or null if class not annotated with {@link Response}. */ public static ResponseBeanMeta create(MethodInfo m, AnnotationWorkList annotations) { if (! (m.hasAnnotation(Response.class) || m.getReturnType().unwrap(Value.class,Optional.class).hasAnnotation(Response.class))) return null; Builder b = new Builder(annotations); b.apply(m.getReturnType().unwrap(Value.class, Optional.class).innerType()); m.forEachAnnotation(Response.class, x -> true, x -> b.apply(x)); m.forEachAnnotation(StatusCode.class, x -> true, x -> b.apply(x)); return b.build(); } /** * Create metadata from specified method parameter. * * @param mpi The method parameter. * @param annotations The annotations to apply to any new part serializers or parsers. * @return Metadata about the class, or null if class not annotated with {@link Response}. */ public static ResponseBeanMeta create(ParamInfo mpi, AnnotationWorkList annotations) { if (mpi.hasNoAnnotation(Response.class)) return null; Builder b = new Builder(annotations); b.apply(mpi.getParameterType().unwrap(Value.class, Optional.class).innerType()); mpi.forEachAnnotation(Response.class, x-> true, x -> b.apply(x)); mpi.forEachAnnotation(StatusCode.class, x -> true, x -> b.apply(x)); return b.build(); } //----------------------------------------------------------------------------------------------------------------- // Instance //----------------------------------------------------------------------------------------------------------------- private final ClassMeta cm; private final Map properties; private final int code; private final Map headerMethods; private final ResponseBeanPropertyMeta statusMethod, contentMethod; private final Optional partSerializer; private final Optional partParser; private final HttpPartSchema schema; ResponseBeanMeta(Builder b) { this.cm = b.cm; this.code = b.code; this.partSerializer = optional(b.partSerializer).map(x -> HttpPartSerializer.creator().type(x).apply(b.annotations).create()); this.partParser = optional(b.partParser).map(x -> HttpPartParser.creator().type(x).apply(b.annotations).create()); this.schema = b.schema.build(); Map properties = map(); Map hm = map(); b.headerMethods.forEach((k,v) -> { ResponseBeanPropertyMeta pm = v.build(partSerializer, partParser); hm.put(k, pm); properties.put(pm.getGetter().getName(), pm); }); this.headerMethods = unmodifiable(hm); this.contentMethod = b.contentMethod == null ? null : b.contentMethod.schema(schema).build(partSerializer, partParser); this.statusMethod = b.statusMethod == null ? null : b.statusMethod.build(empty(), empty()); if (contentMethod != null) properties.put(contentMethod.getGetter().getName(), contentMethod); if (statusMethod != null) properties.put(statusMethod.getGetter().getName(), statusMethod); this.properties = unmodifiable(properties); } static class Builder { ClassMeta cm; int code; AnnotationWorkList annotations; Class partSerializer; Class partParser; HttpPartSchema.Builder schema = HttpPartSchema.create(); Map headerMethods = map(); ResponseBeanPropertyMeta.Builder contentMethod; ResponseBeanPropertyMeta.Builder statusMethod; Builder(AnnotationWorkList annotations) { this.annotations = annotations; } Builder apply(Type t) { Class c = ClassUtils.toClass(t); this.cm = BeanContext.DEFAULT.getClassMeta(c); ClassInfo ci = cm.getInfo(); ci.forEachPublicMethod(x -> true, x -> { assertNoInvalidAnnotations(x, Query.class, FormData.class); if (x.hasAnnotation(Header.class)) { assertNoArgs(x, Header.class); assertReturnNotVoid(x, Header.class); HttpPartSchema s = HttpPartSchema.create(x.getAnnotation(Header.class), x.getPropertyName()); headerMethods.put(s.getName(), ResponseBeanPropertyMeta.create(RESPONSE_HEADER, s, x)); } else if (x.hasAnnotation(StatusCode.class)) { assertNoArgs(x, Header.class); assertReturnType(x, Header.class, int.class, Integer.class); statusMethod = ResponseBeanPropertyMeta.create(RESPONSE_STATUS, x); } else if (x.hasAnnotation(Content.class)) { if (x.hasNoParams()) assertReturnNotVoid(x, Header.class); else assertArgType(x, Header.class, OutputStream.class, Writer.class); contentMethod = ResponseBeanPropertyMeta.create(RESPONSE_BODY, x); } }); return this; } Builder apply(Response a) { if (a != null) { if (isNotVoid(a.serializer())) partSerializer = a.serializer(); if (isNotVoid(a.parser())) partParser = a.parser(); schema.apply(a.schema()); } return this; } Builder apply(StatusCode a) { if (a != null) { if (a.value().length > 0) code = a.value()[0]; } return this; } ResponseBeanMeta build() { return new ResponseBeanMeta(this); } } /** * Returns the HTTP status code. * * @return The HTTP status code. */ public int getCode() { return code; } /** * Returns the schema information about the response object. * * @return The schema information about the response object. */ public HttpPartSchema getSchema() { return schema; } /** * Returns metadata about the @Header-annotated methods. * * @return Metadata about the @Header-annotated methods, or an empty collection if none exist. */ public Collection getHeaderMethods() { return headerMethods.values(); } /** * Returns the @Content-annotated method. * * @return The @Content-annotated method, or null if it doesn't exist. */ public ResponseBeanPropertyMeta getContentMethod() { return contentMethod; } /** * Returns the @StatusCode-annotated method. * * @return The @StatusCode-annotated method, or null if it doesn't exist. */ public ResponseBeanPropertyMeta getStatusMethod() { return statusMethod; } /** * Returns the part serializer to use to serialize this response. * * @return The part serializer to use to serialize this response. */ public Optional getPartSerializer() { return partSerializer; } /** * Returns metadata about the class. * * @return Metadata about the class. */ public ClassMeta getClassMeta() { return cm; } /** * Returns metadata about the bean property with the specified method getter name. * * @param name The bean method getter name. * @return Metadata about the bean property, or null if none found. */ public ResponseBeanPropertyMeta getProperty(String name) { return properties.get(name); } /** * Returns all the annotated methods on this bean. * * @return All the annotated methods on this bean. */ public Collection getProperties() { return properties.values(); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy