001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.rest.client.remote;
018
019import static org.apache.juneau.httppart.HttpPartType.*;
020
021import java.util.*;
022
023import org.apache.juneau.commons.reflect.*;
024import org.apache.juneau.cp.*;
025import org.apache.juneau.http.annotation.*;
026import org.apache.juneau.httppart.*;
027
028/**
029 * Represents the metadata about an annotated argument of a method on a REST proxy class.
030 *
031 * <h5 class='section'>See Also:</h5><ul>
032 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestProxyBasics">REST Proxy Basics</a>
033 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauRestClientBasics">juneau-rest-client Basics</a>
034 * </ul>
035 */
036public class RemoteOperationArg {
037
038   private static final AnnotationProvider AP = AnnotationProvider.INSTANCE;
039
040   static RemoteOperationArg create(ParameterInfo mpi) {
041      int i = mpi.getIndex();
042      if (AP.has(Header.class, mpi)) {
043         return new RemoteOperationArg(i, HEADER, HttpPartSchema.create(Header.class, mpi));
044      } else if (AP.has(Query.class, mpi)) {
045         return new RemoteOperationArg(i, QUERY, HttpPartSchema.create(Query.class, mpi));
046      } else if (AP.has(FormData.class, mpi)) {
047         return new RemoteOperationArg(i, FORMDATA, HttpPartSchema.create(FormData.class, mpi));
048      } else if (AP.has(PathRemainder.class, mpi)) {
049         // PathRemainder is equivalent to @Path("/*")
050         // Create with schema properties but override name to "/*"
051         var schema = HttpPartSchema.create(PathRemainder.class, mpi);
052         return new RemoteOperationArg(i, PATH, schema, "/*");
053      } else if (AP.has(Path.class, mpi)) {
054         return new RemoteOperationArg(i, PATH, HttpPartSchema.create(Path.class, mpi));
055      } else if (AP.has(Content.class, mpi)) {
056         return new RemoteOperationArg(i, BODY, HttpPartSchema.create(Content.class, mpi));
057      }
058      return null;
059   }
060
061   private final int index;
062   private final HttpPartType partType;
063   private final Optional<HttpPartSerializer> serializer;
064
065   private final HttpPartSchema schema;
066
067   RemoteOperationArg(int index, HttpPartType partType, HttpPartSchema schema) {
068      this.index = index;
069      this.partType = partType;
070      this.serializer = BeanCreator.of(HttpPartSerializer.class).type(schema.getSerializer()).execute();
071      this.schema = schema;
072   }
073
074   RemoteOperationArg(int index, HttpPartType partType, HttpPartSchema schema, String overrideName) {
075      this.index = index;
076      this.partType = partType;
077      this.serializer = BeanCreator.of(HttpPartSerializer.class).type(schema.getSerializer()).execute();
078      // Create a new schema with the overridden name
079      this.schema = HttpPartSchema.create().name(overrideName).build();
080   }
081
082   /**
083    * Returns the method argument index.
084    *
085    * @return The method argument index.
086    */
087   public int getIndex() { return index; }
088
089   /**
090    * Returns the name of the HTTP part.
091    *
092    * @return The name of the HTTP part.
093    */
094   public String getName() { return schema.getName(); }
095
096   /**
097    * Returns the HTTP part type.
098    *
099    * @return The HTTP part type.  Never <jk>null</jk>.
100    */
101   public HttpPartType getPartType() { return partType; }
102
103   /**
104    * Returns the HTTP part schema information about this part.
105    *
106    * @return The HTTP part schema information, or <jk>null</jk> if not found.
107    */
108   public HttpPartSchema getSchema() { return schema; }
109
110   /**
111    * Returns the HTTP part serializer to use for serializing this part.
112    *
113    * @return The HTTP part serializer, or the default if not specified.
114    */
115   public Optional<HttpPartSerializer> getSerializer() { return serializer; }
116
117   /**
118    * Returns whether the <c>skipIfEmpty</c> flag was found in the schema.
119    *
120    * @return <jk>true</jk> if the <c>skipIfEmpty</c> flag was found in the schema.
121    */
122   public boolean isSkipIfEmpty() { return schema.isSkipIfEmpty(); }
123}