001// ***************************************************************************************************************************
002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
003// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
005// * with the License.  You may obtain a copy of the License at                                                              *
006// *                                                                                                                         *
007// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
008// *                                                                                                                         *
009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
011// * specific language governing permissions and limitations under the License.                                              *
012// ***************************************************************************************************************************
013package org.apache.juneau.rest.client.remote;
014
015import static org.apache.juneau.http.remote.RemoteUtils.*;
016
017import java.lang.reflect.*;
018import java.util.*;
019import java.util.concurrent.*;
020
021import org.apache.juneau.*;
022import org.apache.juneau.http.remote.RemoteReturn;
023import org.apache.juneau.http.annotation.*;
024import org.apache.juneau.httppart.bean.*;
025import org.apache.juneau.reflect.*;
026
027/**
028 * Represents the metadata about the returned object of a method on a remote proxy interface.
029 *
030 * <h5 class='section'>See Also:</h5><ul>
031 *    <li class='link'><a class="doclink" href="../../../../../../index.html#jrc.Proxies">REST Proxies</a>
032 *    <li class='link'><a class="doclink" href="../../../../../../index.html#juneau-rest-client">juneau-rest-client</a>
033 * </ul>
034 */
035public final class RemoteOperationReturn {
036
037   private final Type returnType;
038   private final RemoteReturn returnValue;
039   private final ResponseBeanMeta meta;
040   private boolean isFuture, isCompletableFuture;
041
042   RemoteOperationReturn(MethodInfo m) {
043      ClassInfo rt = m.getReturnType();
044
045      AnnotationList al = m.getAnnotationList(REMOTE_OP_GROUP);
046      if (al.isEmpty())
047         al = m.getReturnType().unwrap(Value.class,Optional.class).getAnnotationList(REMOTE_OP_GROUP);
048
049      RemoteReturn rv = null;
050
051      if (rt.is(Future.class)) {
052         isFuture = true;
053         rt = ClassInfo.of(((ParameterizedType)rt.innerType()).getActualTypeArguments()[0]);
054      } else if (rt.is(CompletableFuture.class)) {
055         isCompletableFuture = true;
056         rt = ClassInfo.of(((ParameterizedType)rt.innerType()).getActualTypeArguments()[0]);
057      }
058
059      if (rt.is(void.class) || rt.is(Void.class)) {
060         rv = RemoteReturn.NONE;
061      } else {
062         Value<RemoteReturn> v = Value.of(RemoteReturn.BODY);
063         al.forEachValue(RemoteReturn.class, "returns", x -> true, x -> v.set(x));
064         rv = v.get();
065      }
066
067      if (rt.hasAnnotation(Response.class) && rt.isInterface()) {
068         this.meta = ResponseBeanMeta.create(m, AnnotationWorkList.create());
069         rv = RemoteReturn.BEAN;
070      } else {
071         this.meta = null;
072      }
073
074      this.returnType = rt.innerType();
075      this.returnValue = rv;
076   }
077
078   /**
079    * Returns schema information about the HTTP part.
080    *
081    * @return Schema information about the HTTP part, or <jk>null</jk> if not found.
082    */
083   public ResponseBeanMeta getResponseBeanMeta() {
084      return meta;
085   }
086
087   /**
088    * Returns the class type of the method return.
089    *
090    * @return The class type of the method return.
091    */
092   public Type getReturnType() {
093      return returnType;
094   }
095
096   /**
097    * Returns <jk>true</jk> if the return is wrapped in a {@link Future}.
098    *
099    * @return <jk>true</jk> if the return is wrapped in a {@link Future}.
100    */
101   public boolean isFuture() {
102      return isFuture;
103   }
104
105   /**
106    * Returns <jk>true</jk> if the return is wrapped in a {@link CompletableFuture}.
107    *
108    * @return <jk>true</jk> if the return is wrapped in a {@link CompletableFuture}.
109    */
110   public boolean isCompletableFuture() {
111      return isCompletableFuture;
112   }
113
114   /**
115    * Specifies whether the return value is the body of the request or the HTTP status.
116    *
117    * @return The type of value returned.
118    */
119   public RemoteReturn getReturnValue() {
120      return returnValue;
121   }
122}