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.Utils.*;
021
022import java.lang.annotation.*;
023import java.lang.reflect.*;
024import java.util.*;
025
026import org.apache.juneau.annotation.*;
027import org.apache.juneau.commons.reflect.*;
028import org.apache.juneau.cp.*;
029import org.apache.juneau.http.annotation.*;
030import org.apache.juneau.httppart.*;
031
032/**
033 * Represents the metadata gathered from a getter method of a class annotated with {@link Request}.
034 *
035 * <h5 class='section'>See Also:</h5><ul>
036 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/HttpPartSerializersParsers">HTTP Part Serializers and Parsers</a>
037 * </ul>
038 */
039public class RequestBeanPropertyMeta {
040
041   private static final AnnotationProvider AP = AnnotationProvider.INSTANCE;
042
043   static class Builder {
044      HttpPartType partType;
045      HttpPartSchema schema;
046      Method getter;
047
048      RequestBeanPropertyMeta build(HttpPartSerializer serializer, HttpPartParser parser) {
049         return new RequestBeanPropertyMeta(this, serializer, parser);
050      }
051
052      Builder getter(Method value) {
053         getter = value;
054         return this;
055      }
056
057      Builder partType(HttpPartType value) {
058         partType = value;
059         return this;
060      }
061
062      Builder schema(HttpPartSchema value) {
063         schema = value;
064         return this;
065      }
066   }
067
068   static RequestBeanPropertyMeta.Builder create(HttpPartType partType, Class<? extends Annotation> c, MethodInfo m) {
069      var sb = HttpPartSchema.create().name(m.getPropertyName());
070      var ap = AP;
071      rstream(ap.find(Schema.class, m)).forEach(x -> sb.apply(x.inner()));
072      rstream(ap.find(c, m)).forEach(x -> sb.apply(x.inner()));
073      return new Builder().partType(partType).schema(sb.build()).getter(m.inner());
074   }
075
076   private final Method getter;
077   private final HttpPartType partType;
078   private final Optional<HttpPartSerializer> serializer;
079   private final HttpPartParser parser;
080
081   private final HttpPartSchema schema;
082
083   RequestBeanPropertyMeta(Builder b, HttpPartSerializer serializer, HttpPartParser parser) {
084      partType = b.partType;
085      schema = b.schema;
086      getter = b.getter;
087      this.serializer = opt(schema.getSerializer() == null ? serializer : BeanCreator.of(HttpPartSerializer.class).type(schema.getSerializer()).run());
088      this.parser = schema.getParser() == null ? parser : BeanCreator.of(HttpPartParser.class).type(schema.getParser()).run();
089   }
090
091   /**
092    * Returns the name of the Java method getter that defines this property.
093    *
094    * @return
095    *    The name of the Java method getter that defines this property.
096    *    <br>Never <jk>null</jk>.
097    */
098   public Method getGetter() { return getter; }
099
100   /**
101    * Returns the parser to use for parsing the bean property value.
102    *
103    * @param _default The default parsing to use if not defined on the annotation.
104    * @return The parsing to use for serializing the bean property value.
105    */
106   public HttpPartParserSession getParser(HttpPartParserSession _default) {
107      return parser == null ? _default : parser.getPartSession();
108   }
109
110   /**
111    * Returns the HTTP part name for this property (query parameter name for example).
112    *
113    * @return The HTTP part name, or <jk>null</jk> if it doesn't have a part name.
114    */
115   public String getPartName() { return schema == null ? null : schema.getName(); }
116
117   /**
118    * Returns the HTTP part type for this property (query parameter for example).
119    *
120    * @return
121    *    The HTTP part type for this property.
122    *    <br>Never <jk>null</jk>.
123    */
124   public HttpPartType getPartType() { return partType; }
125
126   /**
127    * Returns the schema information gathered from annotations on the method and return type.
128    *
129    * @return
130    *    The schema information gathered from annotations on the method and return type.
131    *    <br>Never <jk>null</jk>.
132    */
133   public HttpPartSchema getSchema() { return schema; }
134
135   /**
136    * Returns the serializer to use for serializing the bean property value.
137    *
138    * @return The serializer to use for serializing the bean property value.
139    */
140   public Optional<HttpPartSerializer> getSerializer() { return serializer; }
141}