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.internal.StringUtils.*; 016import java.lang.reflect.*; 017import java.util.*; 018 019import org.apache.http.*; 020import org.apache.juneau.collections.*; 021import org.apache.juneau.http.*; 022import org.apache.juneau.http.header.*; 023import org.apache.juneau.http.remote.*; 024import org.apache.juneau.reflect.*; 025import org.apache.juneau.svl.*; 026 027/** 028 * Contains the meta-data about a REST proxy class. 029 * 030 * <p> 031 * Captures the information in {@link org.apache.juneau.http.remote.Remote @Remote} and {@link org.apache.juneau.http.remote.RemoteMethod @RemoteMethod} annotations for 032 * caching and reuse. 033 * 034 * <ul class='seealso'> 035 * <li class='link'>{@doc RestcProxies} 036 * </ul> 037 */ 038public class RemoteMeta { 039 040 private final Map<Method,RemoteMethodMeta> methods; 041 private final HeaderSupplier headerSupplier = HeaderSupplier.create().resolving(); 042 043 /** 044 * Constructor. 045 * 046 * @param c The interface class annotated with a {@link org.apache.juneau.http.remote.Remote @Remote} annotation (optional). 047 */ 048 @SuppressWarnings("deprecation") 049 public RemoteMeta(Class<?> c) { 050 String path = ""; 051 052 ClassInfo ci = ClassInfo.of(c); 053 for (RemoteResource r : ci.getAnnotations(RemoteResource.class)) 054 if (! r.path().isEmpty()) 055 path = trimSlashes(r.path()); 056 for (org.apache.juneau.http.remote.RemoteResource r : ci.getAnnotations(org.apache.juneau.http.remote.RemoteResource.class)) 057 if (! r.path().isEmpty()) 058 path = trimSlashes(r.path()); 059 060 String versionHeader = "X-Client-Version", clientVersion = null; 061 062 for (Remote r : ci.getAnnotations(Remote.class)) { 063 if (! r.path().isEmpty()) 064 path = trimSlashes(resolve(r.path())); 065 for (String h : r.headers()) 066 headerSupplier.add(BasicHeader.ofPair(resolve(h))); 067 if (! r.version().isEmpty()) 068 clientVersion = resolve(r.version()); 069 if (! r.versionHeader().isEmpty()) 070 versionHeader = resolve(r.versionHeader()); 071 if (r.headerSupplier() != HeaderSupplier.Null.class) { 072 try { 073 headerSupplier.add(r.headerSupplier().newInstance()); 074 } catch (Exception e) { 075 throw new RuntimeException("Could not instantiate HeaderSupplier class.", e); 076 } 077 } 078 } 079 080 if (clientVersion != null) 081 headerSupplier.add(BasicStringHeader.of(versionHeader, clientVersion)); 082 083 AMap<Method,RemoteMethodMeta> methods = AMap.of(); 084 for (MethodInfo m : ci.getPublicMethods()) 085 methods.put(m.inner(), new RemoteMethodMeta(path, m.inner(), "GET")); 086 087 this.methods = methods.unmodifiable(); 088 } 089 090 /** 091 * Returns the metadata about the specified method on this resource proxy. 092 * 093 * @param m The method to look up. 094 * @return Metadata about the method or <jk>null</jk> if no metadata was found. 095 */ 096 public RemoteMethodMeta getMethodMeta(Method m) { 097 return methods.get(m); 098 } 099 100 /** 101 * Returns the headers to set on all requests. 102 * 103 * @return The headers to set on all requests. 104 */ 105 public Iterable<Header> getHeaders() { 106 return headerSupplier; 107 } 108 109 //------------------------------------------------------------------------------------------------------------------ 110 // Helper methods. 111 //------------------------------------------------------------------------------------------------------------------ 112 113 private static String resolve(String s) { 114 return VarResolver.DEFAULT.resolve(s); 115 } 116}