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