001/*
002 * HA-JDBC: High-Availability JDBC
003 * Copyright (c) 2004-2007 Paul Ferraro
004 * 
005 * This library is free software; you can redistribute it and/or modify it 
006 * under the terms of the GNU Lesser General Public License as published by the 
007 * Free Software Foundation; either version 2.1 of the License, or (at your 
008 * option) any later version.
009 * 
010 * This library is distributed in the hope that it will be useful, but WITHOUT
011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 
013 * for more details.
014 * 
015 * You should have received a copy of the GNU Lesser General Public License
016 * along with this library; if not, write to the Free Software Foundation, 
017 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018 * 
019 * Contact: ferraro@users.sourceforge.net
020 */
021package net.sf.hajdbc.distributable;
022
023import java.util.HashSet;
024import java.util.Iterator;
025import java.util.Set;
026
027import org.jgroups.Address;
028import org.jgroups.Channel;
029import org.jgroups.MembershipListener;
030import org.jgroups.View;
031
032/**
033 * @author Paul Ferraro
034 */
035public abstract class AbstractMembershipListener implements MembershipListener
036{
037        protected Channel channel;
038        private Set<Address> addressSet = new HashSet<Address>();
039
040        protected AbstractMembershipListener(Channel channel)
041        {
042                this.channel = channel;
043                
044                this.channel.setOpt(Channel.LOCAL, false);
045        }
046        
047        /**
048         * @see org.jgroups.MembershipListener#block()
049         */
050        @Override
051        public final void block()
052        {
053                // Do nothing
054        }
055
056        /**
057         * @see org.jgroups.MembershipListener#suspect(org.jgroups.Address)
058         */
059        @Override
060        public final void suspect(Address address)
061        {
062                // Do nothing
063        }
064        
065        /**
066         * @see org.jgroups.MembershipListener#viewAccepted(org.jgroups.View)
067         */
068        @Override
069        public final void viewAccepted(View view)
070        {
071                synchronized (this.addressSet)
072                {
073                        Iterator<Address> addresses = this.addressSet.iterator();
074                        
075                        while (addresses.hasNext())
076                        {
077                                Address address = addresses.next();
078                                
079                                if (!view.containsMember(address))
080                                {
081                                        addresses.remove();
082                                        
083                                        this.memberLeft(address);
084                                }
085                        }
086                        
087                        Address localAddress = this.channel.getLocalAddress();
088                        
089                        for (Address address: view.getMembers())
090                        {
091                                // Track remote members only
092                                if (!address.equals(localAddress) && this.addressSet.add(address))
093                                {
094                                        this.memberJoined(address);
095                                }
096                        }
097                }
098        }
099
100        public int getMembershipSize()
101        {
102                synchronized (this.addressSet)
103                {
104                        return this.addressSet.size();
105                }
106        }
107        
108        public boolean isMembershipEmpty()
109        {
110                synchronized (this.addressSet)
111                {
112                        return this.addressSet.isEmpty();
113                }
114        }
115
116        protected abstract void memberJoined(Address address);
117        
118        protected abstract void memberLeft(Address address);
119}