1 /* 2 * Copyright (c) 1998-2004 The Jgroup Team. 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU Lesser General Public License version 2 as 6 * published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU Lesser General Public License for more details. 12 * 13 * You should have received a copy of the GNU Lesser General Public License 14 * along with this program; if not, write to the Free Software 15 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 16 * 17 */ 18 19 package jgroup.relacs.gmi; 20 21 import java.io.Serializable; 22 import java.lang.reflect.Method; 23 import java.rmi.Remote; 24 import java.util.HashMap; 25 import java.util.Iterator; 26 import java.util.Map; 27 28 import org.apache.log4j.Logger; 29 30 /** 31 * Table mapping a method (represented by a hash of the method or by 32 * a <code>Method</code> object) to its <code>MethodDetails</code> object. 33 * 34 * The mapping from <code>Method</code> objects will only be populated 35 * on the client-side since those are only used there. 36 * 37 * @author Hein Meling 38 * @since Jgroup 3.0 39 */ 40 public class MethodTable 41 implements Serializable, Iterable<MethodDetails> 42 { 43 44 private static final long serialVersionUID = -7706887009118848315L; 45 46 //////////////////////////////////////////////////////////////////////////////////////////// 47 // Logger 48 //////////////////////////////////////////////////////////////////////////////////////////// 49 50 /** Obtain logger for this class */ 51 private static final Logger log = Logger.getLogger(MethodTable.class); 52 53 54 //////////////////////////////////////////////////////////////////////////////////////////// 55 // Fields 56 //////////////////////////////////////////////////////////////////////////////////////////// 57 58 /** Table of methods (mapping from hash value to method details object) */ 59 private final Map<Long,MethodDetails> table = new HashMap<Long,MethodDetails>(); 60 61 /** Table mapping from method to method details object (only client-side) */ 62 private transient Map<Method,MethodDetails> methTable; 63 64 65 //////////////////////////////////////////////////////////////////////////////////////////// 66 // Constructor 67 //////////////////////////////////////////////////////////////////////////////////////////// 68 69 public MethodTable() 70 { 71 } 72 73 74 //////////////////////////////////////////////////////////////////////////////////////////// 75 // Methods 76 //////////////////////////////////////////////////////////////////////////////////////////// 77 78 /** 79 * Add remote methods implemented by the given server to this 80 * method table. All methods defined in a <code>Remote</code> 81 * interface will be added, and their associated invocation 82 * semantics details will be computed. 83 */ 84 public void addMethods(Object server) 85 { 86 /* 87 * Find all the remote interfaces implemented by the given 88 * server object, and compute relevant method information. 89 */ 90 Class serverClass = server.getClass(); 91 Class[] interfaces = serverClass.getInterfaces(); 92 for (int i = 0; i < interfaces.length; i++) { 93 if (Remote.class.isAssignableFrom(interfaces[i])) { 94 Method methods[] = interfaces[i].getMethods(); 95 for (int j = 0; j < methods.length; j++) { 96 MethodDetails meth = new MethodDetails(methods[j], server); 97 table.put(meth.getHash(), meth); 98 if (log.isDebugEnabled()) 99 log.debug("Adding: " + meth); 100 } 101 } 102 } 103 } 104 105 /** 106 * Get the method details associated with the given hash value. 107 */ 108 public MethodDetails get(long hash) 109 { 110 return table.get(hash); 111 } 112 113 /** 114 * Return the method details object associated with the given method. 115 */ 116 public MethodDetails get(Method m) 117 { 118 if (methTable == null) { 119 methTable = new HashMap<Method,MethodDetails>(); 120 } 121 MethodDetails method = methTable.get(m); 122 if (method == null) { 123 long hash = MethodDetails.computeHash(m); 124 method = get(hash); 125 methTable.put(m, method); 126 } 127 return method; 128 } 129 130 131 //////////////////////////////////////////////////////////////////////////////////////////// 132 // Methods from Iterable<MethodDetails> 133 //////////////////////////////////////////////////////////////////////////////////////////// 134 135 public Iterator<MethodDetails> iterator() 136 { 137 return table.values().iterator(); 138 } 139 140 141 //////////////////////////////////////////////////////////////////////////////////////////// 142 // Object methods 143 //////////////////////////////////////////////////////////////////////////////////////////// 144 145 public String toString() 146 { 147 StringBuilder buf = new StringBuilder("MethodTable["); 148 for (Map.Entry<Long,MethodDetails> entry : table.entrySet()) { 149 MethodDetails meth = entry.getValue(); 150 buf.append("\n"); 151 buf.append(entry.getKey()); 152 buf.append(" -> "); 153 buf.append(meth); 154 Object server = meth.getServer(); 155 if (server != null) { 156 // the server object is only available on the server-side 157 buf.append("; server="); 158 buf.append(server.getClass().getSimpleName()); 159 } 160 } 161 buf.append("]"); 162 return buf.toString(); 163 } 164 165 } // END MethodTable