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.http.remote;
018
019import static org.apache.juneau.commons.utils.StringUtils.*;
020
021import java.lang.reflect.*;
022
023import org.apache.juneau.commons.reflect.*;
024
025/**
026 * Contains the meta-data about a Java method on a remote class.
027 *
028 * <p>
029 * Captures the information in {@link Remote @Remote} annotations for caching and reuse.
030 *
031 * <h5 class='section'>See Also:</h5><ul>
032 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestRpc">REST/RPC</a>
033 * </ul>
034 */
035public class RrpcInterfaceMethodMeta {
036
037   /**
038    * Given a Java method, returns the arguments signature.
039    *
040    * @param m The Java method.
041    * @param full Whether fully-qualified names should be used for arguments.
042    * @return The arguments signature for the specified method.
043    */
044   private static String getMethodArgsSignature(Method m) {
045      var sb = new StringBuilder(128);
046      Class<?>[] pt = m.getParameterTypes();
047      if (pt.length == 0)
048         return "";
049      sb.append('(');
050      for (var i = 0; i < pt.length; i++) {
051         var pti = ClassInfo.of(pt[i]);
052         if (i > 0)
053            sb.append(',');
054         pti.appendNameFormatted(sb, ClassNameFormat.FULL, true, '$', ClassArrayFormat.BRACKETS);
055      }
056      sb.append(')');
057      return sb.toString();
058   }
059
060   private final String url, path;
061
062   private final Method method;
063
064   /**
065    * Constructor.
066    *
067    * @param restUrl The absolute URL of the REST interface backing the interface proxy.
068    * @param m The Java method.
069    */
070   public RrpcInterfaceMethodMeta(String restUrl, Method m) {
071      this.method = m;
072      this.path = m.getName() + '/' + getMethodArgsSignature(m);
073      this.url = trimSlashes(restUrl) + '/' + urlEncode(path);
074   }
075
076   /**
077    * Returns the underlying Java method that this metadata is about.
078    *
079    * @return
080    *    The underlying Java method that this metadata is about.
081    *    <br>Never <jk>null</jk>.
082    */
083   public Method getJavaMethod() { return method; }
084
085   /**
086    * Returns the HTTP path of this method.
087    *
088    * @return
089    *    The HTTP path of this method relative to the parent interface.
090    *    <br>Never <jk>null</jk>.
091    *    <br>Never has leading or trailing slashes.
092    */
093   public String getPath() { return path; }
094
095   /**
096    * Returns the absolute URL of the REST interface invoked by this Java method.
097    *
098    * @return The absolute URL of the REST interface, never <jk>null</jk>.
099    */
100   public String getUri() { return url; }
101}