001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.juneau.httppart.bean; 018 019import static org.apache.juneau.commons.utils.CollectionUtils.*; 020import static org.apache.juneau.commons.utils.Shorts.*; 021 022import java.lang.annotation.*; 023import java.lang.reflect.*; 024import java.util.*; 025 026import org.apache.juneau.commons.*; 027import org.apache.juneau.commons.httppart.*; 028import org.apache.juneau.commons.inject.*; 029import org.apache.juneau.commons.reflect.*; 030import org.apache.juneau.http.*; 031import org.apache.juneau.marshall.httppart.*; 032 033/** 034 * Represents the metadata gathered from a getter method of a class annotated with {@link Request}. 035 * 036 * <h5 class='section'>See Also:</h5><ul> 037 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/HttpPartSerializersParsers">HTTP Part Serializers and Parsers</a> 038 * </ul> 039 */ 040public class RequestBeanPropertyMeta { 041 042 private static final AnnotationProvider AP = AnnotationProvider.INSTANCE; 043 044 static class Builder { 045 HttpPartType partType; 046 HttpPartSchema schema; 047 Method getter; 048 049 RequestBeanPropertyMeta build(HttpPartSerializer serializer, HttpPartParser parser) { 050 return new RequestBeanPropertyMeta(this, serializer, parser); 051 } 052 053 Builder getter(Method value) { 054 getter = value; 055 return this; 056 } 057 058 Builder partType(HttpPartType value) { 059 partType = value; 060 return this; 061 } 062 063 Builder schema(HttpPartSchema value) { 064 schema = value; 065 return this; 066 } 067 } 068 069 static RequestBeanPropertyMeta.Builder create(HttpPartType partType, Class<? extends Annotation> c, MethodInfo m) { 070 var sb = HttpPartSchema.create().name(m.getPropertyName()); 071 var ap = AP; 072 rstream(ap.find(Schema.class, m)).forEach(x -> sb.apply(x.inner())); 073 rstream(ap.find(c, m)).forEach(x -> sb.apply(x.inner())); 074 return new Builder().partType(partType).schema(sb.build()).getter(m.inner()); 075 } 076 077 private final Method getter; 078 private final HttpPartType partType; 079 private final Optional<HttpPartSerializer> serializer; 080 private final HttpPartParser parser; 081 082 private final HttpPartSchema schema; 083 084 @SuppressWarnings({ 085 "unchecked" // Type erasure on reflective/generic cast; element type is verified at call site 086 }) 087 RequestBeanPropertyMeta(Builder b, HttpPartSerializer serializer, HttpPartParser parser) { 088 partType = b.partType; 089 schema = b.schema; 090 getter = b.getter; 091 this.serializer = o(BeanInstantiator.createOrDefault((Class<HttpPartSerializer>) schema.getSerializer(), serializer)); 092 this.parser = BeanInstantiator.createOrDefault((Class<HttpPartParser>) schema.getParser(), parser); 093 } 094 095 /** 096 * Returns the name of the Java method getter that defines this property. 097 * 098 * @return 099 * The name of the Java method getter that defines this property. 100 * <br>Never <jk>null</jk>. 101 */ 102 public Method getGetter() { return getter; } 103 104 /** 105 * Returns the parser to use for parsing the bean property value. 106 * 107 * @param defaultParser The default parser to use if not defined on the annotation. Can be <jk>null</jk>. 108 * @return 109 * The parser to use for parsing the bean property value, or <c>defaultParser</c> (which can be <jk>null</jk>) 110 * if no parser is configured on the annotation. 111 */ 112 public HttpPartParserSession getParser(HttpPartParserSession defaultParser) { 113 return parser == null ? defaultParser : parser.getPartSession(); 114 } 115 116 /** 117 * Returns the HTTP part name for this property (query parameter name for example). 118 * 119 * @return The HTTP part name, or <jk>null</jk> if it doesn't have a part name. 120 */ 121 public String getPartName() { return schema.getName(); } 122 123 /** 124 * Returns the HTTP part type for this property (query parameter for example). 125 * 126 * @return 127 * The HTTP part type for this property. 128 * <br>Never <jk>null</jk>. 129 */ 130 public HttpPartType getPartType() { return partType; } 131 132 /** 133 * Returns the schema information gathered from annotations on the method and return type. 134 * 135 * @return 136 * The schema information gathered from annotations on the method and return type. 137 * <br>Never <jk>null</jk>. 138 */ 139 public HttpPartSchema getSchema() { return schema; } 140 141 /** 142 * Returns the serializer to use for serializing the bean property value. 143 * 144 * @return The serializer to use for serializing the bean property value. 145 */ 146 public Optional<HttpPartSerializer> getSerializer() { return serializer; } 147}