001: // $Id: Membership.java,v 1.9 2006/01/14 13:18:08 belaban Exp $
002:
003: package org.jgroups;
004:
005: import org.apache.commons.logging.Log;
006: import org.apache.commons.logging.LogFactory;
007:
008: import java.util.*;
009:
010: /**
011: * Class to keep track of Addresses.
012: * The membership object holds a vector of Address objects that are in the same membership.
013: * Each unique address can only exist once; i.e., doing Membership.add(existing_address)
014: * will be ignored.
015: */
016: public class Membership implements Cloneable {
017: /* private vector to hold all the addresses */
018: private final LinkedList members = new LinkedList();
019: protected static final Log log = LogFactory
020: .getLog(Membership.class);
021:
022: /**
023: * Public constructor
024: * Creates a member ship object with zero members
025: */
026: public Membership() {
027: }
028:
029: /**
030: * Creates a member ship object with the initial members.
031: * The Address references are copied out of the vector, so that the
032: * vector passed in as parameters is not the same reference as the vector
033: * that the membership class is using
034: *
035: * @param initial_members - a list of members that belong to this membership
036: */
037: public Membership(Collection initial_members) {
038: if (initial_members != null)
039: add(initial_members);
040: }
041:
042: /**
043: * returns a copy (clone) of the members in this membership.
044: * the vector returned is immutable in reference to this object.
045: * ie, modifying the vector that is being returned in this method
046: * will not modify this membership object.
047: *
048: * @return a list of members,
049: */
050: public Vector getMembers() {
051: /*clone so that this objects members can not be manipulated from the outside*/
052: synchronized (members) {
053: return new Vector(members);
054: }
055: }
056:
057: /**
058: * Adds a new member to this membership.
059: * If the member already exist (Address.equals(Object) returns true then the member will
060: * not be added to the membership
061: */
062: public void add(Address new_member) {
063: synchronized (members) {
064: if (new_member != null && !members.contains(new_member)) {
065: members.add(new_member);
066: }
067: }
068: }
069:
070: /**
071: * Adds a list of members to this membership
072: *
073: * @param v - a vector containing Address objects
074: * @throws ClassCastException if v contains objects that don't implement the Address interface
075: * @see #add
076: */
077: public final void add(Collection v) {
078: if (v != null) {
079: for (Iterator it = v.iterator(); it.hasNext();) {
080: Address addr = (Address) it.next();
081: add(addr);
082: }
083: }
084: }
085:
086: /**
087: * removes an member from the membership.
088: * If this member doesn't exist, no action will be performed on the existing membership
089: *
090: * @param old_member - the member to be removed
091: */
092: public void remove(Address old_member) {
093: if (old_member != null) {
094: synchronized (members) {
095: members.remove(old_member);
096: }
097: }
098: }
099:
100: /**
101: * removes all the members contained in v from this membership
102: *
103: * @param v - a vector containing all the members to be removed
104: */
105: public void remove(Collection v) {
106: if (v != null) {
107: synchronized (members) {
108: members.removeAll(v);
109: }
110: }
111: }
112:
113: /**
114: * removes all the members from this membership
115: */
116: public void clear() {
117: synchronized (members) {
118: members.clear();
119: }
120: }
121:
122: /**
123: * Clear the membership and adds all members of v
124: * This method will clear out all the old members of this membership by
125: * invoking the <code>Clear</code> method.
126: * Then it will add all the all members provided in the vector v
127: *
128: * @param v - a vector containing all the members this membership will contain
129: */
130: public void set(Collection v) {
131: clear();
132: if (v != null) {
133: add(v);
134: }
135: }
136:
137: /**
138: * Clear the membership and adds all members of v
139: * This method will clear out all the old members of this membership by
140: * invoking the <code>Clear</code> method.
141: * Then it will add all the all members provided in the vector v
142: *
143: * @param m - a membership containing all the members this membership will contain
144: */
145: public void set(Membership m) {
146: clear();
147: if (m != null) {
148: add(m.getMembers());
149: }
150: }
151:
152: /**
153: * merges membership with the new members and removes suspects
154: * The Merge method will remove all the suspects and add in the new members.
155: * It will do it in the order
156: * 1. Remove suspects
157: * 2. Add new members
158: * the order is very important to notice.
159: *
160: * @param new_mems - a vector containing a list of members (Address) to be added to this membership
161: * @param suspects - a vector containing a list of members (Address) to be removed from this membership
162: */
163: public void merge(Collection new_mems, Collection suspects) {
164: remove(suspects);
165: add(new_mems);
166: }
167:
168: /**
169: * Returns true if the provided member belongs to this membership
170: *
171: * @param member
172: * @return true if the member belongs to this membership
173: */
174: public boolean contains(Address member) {
175: if (member == null)
176: return false;
177: synchronized (members) {
178: return members.contains(member);
179: }
180: }
181:
182: /* Simple inefficient bubble sort, but not used very often (only when merging) */
183: public void sort() {
184: synchronized (members) {
185: Collections.sort(members);
186: }
187: }
188:
189: /**
190: * returns a copy of this membership
191: *
192: * @return an exact copy of this membership
193: */
194: public Membership copy() {
195: return ((Membership) clone());
196: }
197:
198: /**
199: * @return a clone of this object. The list of members is copied to a new
200: * container
201: */
202: public Object clone() {
203: return new Membership(this .members);
204: }
205:
206: /**
207: * Returns the number of addresses in this membership
208: *
209: * @return the number of addresses in this membership
210: */
211: public int size() {
212: synchronized (members) {
213: return members.size();
214: }
215: }
216:
217: /**
218: * Returns the component at the specified index
219: *
220: * @param index - 0..size()-1
221: * @throws ArrayIndexOutOfBoundsException - if the index is negative or not less than the current size of this Membership object.
222: * @see java.util.Vector#elementAt
223: */
224:
225: public Object elementAt(int index) {
226: synchronized (members) {
227: return members.get(index);
228: }
229: }
230:
231: public String toString() {
232: synchronized (members) {
233: return members.toString();
234: }
235: }
236:
237: }
|