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.util.List; 23 import java.util.Random; 24 25 import jgroup.core.JgroupException; 26 import jgroup.core.MemberId; 27 import jgroup.core.protocols.Anycast; 28 import jgroup.core.protocols.Atomic; 29 import jgroup.core.protocols.Internal; 30 import jgroup.core.protocols.Leadercast; 31 import jgroup.core.protocols.Multicast; 32 33 /** 34 * Enumeration of the supported method invocation semantics. 35 * 36 * @author Hein Meling 37 * @since Jgroup 3.0 38 */ 39 public enum MethodSemantics 40 implements Serializable 41 { 42 43 //////////////////////////////////////////////////////////////////////////////////////////// 44 // Enumeration constants 45 //////////////////////////////////////////////////////////////////////////////////////////// 46 47 ANYCAST(Anycast.class), 48 49 LEADERCAST(Leadercast.class) { 50 /* 51 * Returns the leader member always. 52 */ 53 MemberId selectMember(List<MemberId> members) 54 { 55 if (members.isEmpty()) 56 return null; 57 return members.get(0); 58 } 59 }, 60 61 MULTICAST(Multicast.class), 62 63 ATOMIC(Atomic.class), 64 65 INTERNAL(Internal.class); 66 67 68 //////////////////////////////////////////////////////////////////////////////////////////// 69 // Fields 70 //////////////////////////////////////////////////////////////////////////////////////////// 71 72 /** Random number generator for "load-balancing" */ 73 private static final Random rnd = new Random(); 74 75 /** Array representation of the enumerated values */ 76 private static MethodSemantics[] values; 77 78 /** The annotation type associated with this invocation semantics object */ 79 private final Class annotationType; 80 81 82 //////////////////////////////////////////////////////////////////////////////////////////// 83 // Constructor 84 //////////////////////////////////////////////////////////////////////////////////////////// 85 86 private MethodSemantics(Class annotationType) 87 { 88 this.annotationType = annotationType; 89 } 90 91 92 //////////////////////////////////////////////////////////////////////////////////////////// 93 // Methods associated with this enumeration type 94 //////////////////////////////////////////////////////////////////////////////////////////// 95 96 /** 97 * Returns the protocol class object associated with this method semantics 98 * (or protocol annotation type). 99 * 100 * @throws JgroupException Raised if this protocol has no implementation class. 101 */ 102 public Class getProtocol() 103 throws JgroupException 104 { 105 String protocolName = annotationType.getSimpleName(); 106 try { 107 return Class.forName("jgroup.relacs.gmi.protocols." + protocolName); 108 } catch (ClassNotFoundException e) { 109 throw new JgroupException("Unsupported protocol: " + protocolName, e); 110 } 111 } 112 113 /** 114 * Returns the <code>MemberId</code> containing the endpoint that the client 115 * should use for communication with the object group. If the provided list 116 * of members is empty, <code>null</code> may be returned. <p> 117 * 118 * By default the member is selected at random. 119 * 120 * @param endpoints 121 * The list of available endpoints that the client can choose from. 122 */ 123 MemberId selectMember(List<MemberId> members) 124 { 125 String sequencerType = System.getProperty("jgroup.egmi.endpointSelectionScheme", "random"); 126 int size = members.size(); 127 if (size > 0) 128 if (sequencerType.equals("leader")) 129 return members.get(0); 130 else 131 return members.get(rnd.nextInt(size)); 132 else 133 return null; 134 } 135 136 /** 137 * Returns the invocation semantics constant for the given 138 * annotation if such exists. If the given annotation is unrelated 139 * to these constants, <code>null</code> is returned. 140 * 141 * @param annotation 142 * The annotation for which to obtain a constant if such exists. 143 * @return 144 * The constant associated with the given annotation, or <code>null</code> 145 * if no associatation exists to the given annotation. 146 */ 147 static MethodSemantics getInvocationSemantics(Class annotation) 148 { 149 //FIXME can we not find the MethodSemantics object more elegantly. 150 for (MethodSemantics semantics : values()) { 151 if (semantics.annotationType.equals(annotation)) { 152 return semantics; 153 } 154 } 155 return null; 156 } 157 158 /** 159 * Returns the <code>MethodSemantics</code> object for the given ordinal. 160 */ 161 public static MethodSemantics valueOf(int ordinal) 162 { 163 if (values == null) 164 values = values(); 165 return values[ordinal]; 166 } 167 168 } // END MethodSemantics