Clover coverage report - Replica - 1.0-Alpha
Coverage timestamp: Dom Fev 1 2004 17:00:58 WET
file stats: LOC: 457   Methods: 30
NCLOC: 211   Classes: 3
30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover
 
 Source file Conditionals Statements Methods TOTAL
JGroupsGroupManager.java 66,7% 80,3% 83,3% 78,5%
coverage coverage
 1   
 /*
 2   
  * Replica is published under the terms
 3   
  * of the Apache Software License.
 4   
  */
 5   
 package replica.group.jgroups;
 6   
 
 7   
 import java.io.Serializable;
 8   
 import java.util.Iterator;
 9   
 import java.util.List;
 10   
 import java.util.Vector;
 11   
 import java.util.logging.Logger;
 12   
 
 13   
 import org.jgroups.Channel;
 14   
 import org.jgroups.ChannelClosedException;
 15   
 import org.jgroups.ChannelException;
 16   
 import org.jgroups.ChannelFactory;
 17   
 import org.jgroups.ChannelNotConnectedException;
 18   
 import org.jgroups.MembershipListener;
 19   
 import org.jgroups.Message;
 20   
 import org.jgroups.MessageListener;
 21   
 import org.jgroups.View;
 22   
 import org.jgroups.blocks.PullPushAdapter;
 23   
 import org.jgroups.stack.IpAddress;
 24   
 
 25   
 import replica.group.Address;
 26   
 import replica.group.CommunicationException;
 27   
 import replica.group.GroupManager;
 28   
 import replica.group.event.GroupListener;
 29   
 import replica.group.event.MessageEvent;
 30   
 import replica.group.event.SuspectEvent;
 31   
 import replica.group.event.ViewEvent;
 32   
 
 33   
 /**
 34   
  * Implementation of a group communications services provider using the
 35   
  * jgroups.org code.
 36   
  * 
 37   
  * @author Pedro Costa
 38   
  * @author Helder Silva
 39   
  * @since 19/Jan/2004
 40   
  */
 41   
 public class JGroupsGroupManager implements GroupManager {
 42   
     
 43   
     static Logger logger = Logger.getLogger(JGroupsGroupManager.class.getName());
 44   
     
 45   
     String groupName;
 46   
     ChannelFactory channelFactory;
 47   
     String channelProperties;
 48   
     Channel channel;
 49   
     
 50   
     List groupListeneres = new Vector();
 51   
     
 52   
     PullPushAdapter block;
 53   
 
 54   
     /**
 55   
      * Default constructor.
 56   
      */
 57  21
     public JGroupsGroupManager() {
 58  21
         super();
 59   
     }
 60   
 
 61   
     /**
 62   
      * Adds a new listener for Group Events.
 63   
      * @see replica.group.GroupManager#addListener(replica.group.event.GroupListener)
 64   
      */
 65  10
     public void addListener(GroupListener listener) {
 66  10
         logger.fine("Adding new GroupListener.");
 67   
         
 68  10
         groupListeneres.add( listener );
 69   
     }
 70   
 
 71   
     /**
 72   
      * Return the name of the group under management.
 73   
      * 
 74   
      * @see replica.group.GroupManager#getGroupName()
 75   
      */
 76  58
     public String getGroupName() {
 77  58
         return groupName;
 78   
     }
 79   
 
 80   
     /**
 81   
      * Return a list of the current group members addresses.
 82   
      * 
 83   
      * @see replica.group.GroupManager#getGroupView()
 84   
      */
 85  1
     public List getGroupView() {
 86   
         
 87  1
         if( getChannel() == null )
 88  0
             throw new IllegalStateException("You are not connected to any group.");
 89   
             
 90  1
         View view = getChannel().getView();
 91   
         
 92  1
         return convertViewListFromJGroups( view );
 93   
     }
 94   
     
 95   
     /**
 96   
      * Return the local address
 97   
      * 
 98   
      * @see {@link GroupManager#getLocalManager()}
 99   
      */
 100  2
     public Address getLocalAddress(){
 101  2
         return convertJGroupsIpAddressToIpAddress( (IpAddress)getChannel().getLocalAddress() );
 102   
     }
 103   
 
 104   
     /**
 105   
      * Convert a JGroups View into a non specific implementation view.
 106   
      * 
 107   
      */
 108  36
     protected List convertViewListFromJGroups(View view) {
 109   
         
 110  36
         List res = new Vector();
 111   
             
 112  36
         if( view == null )
 113  0
             return res;
 114   
             
 115  36
         List jgroupsList = view.getMembers();
 116   
         
 117  36
         for (Iterator iter = jgroupsList.iterator(); iter.hasNext();) {
 118  62
             replica.group.IpAddress addr = 
 119   
                 convertJGroupsIpAddressToIpAddress( (IpAddress)iter.next() );
 120   
             
 121  60
             res.add(addr);
 122   
         }
 123   
         
 124  34
         return res;
 125   
     }
 126   
     
 127   
     /**
 128   
      * Join a group. You must set the channel and the group name before
 129   
      * calling this method.
 130   
      * 
 131   
      * @see replica.group.GroupManager#joinGroup()
 132   
      * @throws IllegalStateException if the channel is null or the group name
 133   
      *                                     was not set.
 134   
      * @throws CommunicationException if there is a problem connecting to the
 135   
      *                 channel. You can look on the root cause of this exception
 136   
      *                 for further information.
 137   
      */
 138  19
     public void joinGroup() {
 139   
         
 140  19
         if( getChannel() == null || getGroupName() == null )
 141  0
             throw new IllegalStateException(
 142   
                 "You must set the channel and the group name before trying to join."
 143   
             );
 144   
             
 145  19
         if( getChannel().isConnected() )
 146  0
             getChannel().disconnect();
 147  19
         try{
 148  19
             getChannel().connect( getGroupName() );
 149   
         }
 150   
         catch(ChannelClosedException e){
 151  0
             throw new CommunicationException("The channel was closed. Look on the root"+
 152   
             "cause for more information.", e);
 153   
         }
 154   
         catch(ChannelException e){
 155  0
             throw new CommunicationException("Problem connecting to channel. Look on the"+
 156   
             " root cause for more information.", e);
 157   
         }
 158   
         
 159  19
         block = new PullPushAdapter( getChannel() );
 160   
         
 161  19
         block.setListener( new MyMessageListener() );
 162   
         
 163  19
         block.addMembershipListener( new MyMembershipListener() );
 164   
         
 165  19
         block.start();
 166   
         
 167  19
         logger.info("Joined group [" + getGroupName() + "]. Local address [" + getChannel().getLocalAddress() 
 168   
             + "]. View: {"+getChannel().getView()+"}.");
 169   
     }
 170   
 
 171   
     /**
 172   
      * Leave a group.
 173   
      * 
 174   
      * @see replica.group.GroupManager#leaveGroup()
 175   
      */
 176  1
     public void leaveGroup() {
 177   
         
 178  1
         if( getChannel() != null && getChannel().isConnected() )
 179  1
             getChannel().disconnect();
 180   
             
 181  1
         logger.info("Leaved group [" + getGroupName() + "].");
 182   
     }
 183   
 
 184   
     /**
 185   
      * @see replica.group.GroupManager#sendMessage(replica.group.Address, java.lang.Object)
 186   
      */
 187  4
     public void sendMessage(Address rAddr, Object message) {
 188   
         
 189  4
         if( getChannel() == null )
 190  0
             throw new IllegalStateException("You are not connected to any group.");
 191   
         
 192  4
         IpAddress jgroupsRecAddr = null;
 193  4
         if( rAddr != null )
 194  2
             jgroupsRecAddr = 
 195   
                 convertIpAddressToJGroupsIpAddress(
 196   
                     (replica.group.IpAddress)rAddr);
 197  4
         try{
 198  4
             logger.info("Sending message {" + message + "}.");
 199   
             
 200  4
             getChannel().send(null, jgroupsRecAddr,    (Serializable)message);
 201   
         }
 202   
         catch(ChannelClosedException e){
 203  0
             throw new CommunicationException("Channel is closed. Look on the root"+
 204   
                         " cause for more information.",e);
 205   
         }
 206   
         catch(ChannelNotConnectedException e){
 207  0
             throw new CommunicationException("Channel not connected. Look on the root"+
 208   
                         " cause for more information.",e);
 209   
         }
 210   
     }
 211   
     
 212   
     /**
 213   
      * Convert an address in non specific implementation to a jgroups 
 214   
      * class.
 215   
      * 
 216   
      * @param address
 217   
      * @return
 218   
      */
 219  2
     org.jgroups.stack.IpAddress convertIpAddressToJGroupsIpAddress(
 220   
             replica.group.IpAddress address){
 221   
         // TODO using the same class name is confusing
 222   
         //    should revise this.
 223  2
         return new org.jgroups.stack.IpAddress( 
 224   
                         address.getAddress(),
 225   
                         address.getPort() );
 226   
     }
 227   
     
 228   
     /**
 229   
      * Convert an address in jgroups class to an non specific implementation
 230   
      * class.
 231   
      * 
 232   
      * @param address
 233   
      * @return
 234   
      */
 235  72
     replica.group.IpAddress convertJGroupsIpAddressToIpAddress(
 236   
         org.jgroups.stack.IpAddress address){
 237   
         // TODO using the same class name is confusing
 238   
         //    should revise this.
 239  72
         replica.group.IpAddress repAddr = new replica.group.IpAddress();
 240  70
         repAddr.setAddress( address.getIpAddress() );
 241  70
         repAddr.setPort( address.getPort() );
 242   
         
 243  70
         return repAddr;
 244   
     }
 245   
 
 246   
     /**
 247   
      * Short cut method. simply calls #sendMessage(Address, Object) with a null
 248   
      * address.
 249   
      * 
 250   
      * @see replica.group.GroupManager#sendMessage(java.lang.Object)
 251   
      */
 252  2
     public void sendMessage(Object message) {
 253  2
         sendMessage(null, message);
 254   
     }
 255   
 
 256   
     /**
 257   
      * Sets the name of the group to be managed. You still have to call 
 258   
      * joinGroup after setting it's name.
 259   
      * 
 260   
      * @see replica.group.GroupManager#setGroupName(java.lang.String)
 261   
      */
 262  19
     public void setGroupName(String groupName) {
 263  19
         this.groupName = groupName;
 264   
     }
 265   
 
 266   
     /**
 267   
      * @see replica.group.GroupManager#removeListener(replica.group.event.GroupListener)
 268   
      */
 269  1
     public boolean removeListener(GroupListener listener) {
 270  1
         return groupListeneres.remove(listener);
 271   
     }
 272   
     
 273   
     /*
 274   
      *  ==== GroupListener notify methods ====
 275   
      */
 276   
      
 277   
     /**
 278   
      * Notifies GroupListener members that a new message was received.
 279   
      * 
 280   
      */
 281  8
     void notifyMessage(Message message){
 282   
         
 283  8
         MessageEvent event = new MessageEvent(
 284   
                 this, message.getObject(), 
 285   
                 convertJGroupsIpAddressToIpAddress( 
 286   
                         (IpAddress)message.getSrc() ) );
 287   
                         
 288  8
         for (Iterator iter = groupListeneres.iterator(); iter.hasNext();) {
 289  4
             ((GroupListener) iter.next()).message( event);
 290   
         }
 291   
     }
 292   
     
 293   
     /**
 294   
      * Notifies GroupListener members that view has changed.
 295   
      * 
 296   
      * @param view
 297   
      */
 298  34
     void notifyViewChanged(View view){
 299  34
         logger.info("View: {" + view + "}.");
 300   
         
 301  34
         ViewEvent event = new ViewEvent(this,
 302   
             convertViewListFromJGroups( view ) );
 303   
         
 304  32
         for (Iterator iter = groupListeneres.iterator(); iter.hasNext();) {
 305  7
             ((GroupListener) iter.next()).viewChanged( event);
 306   
         }
 307   
     }
 308   
     
 309   
     /**
 310   
      * Notifies GroupListener members that a suspect message was received.
 311   
      * 
 312   
      * @param address
 313   
      */
 314  0
     void notifySuspect(org.jgroups.Address address){
 315   
         
 316  0
         SuspectEvent event = new SuspectEvent( this,
 317   
             convertJGroupsIpAddressToIpAddress((IpAddress)address) );
 318   
             
 319  0
         for (Iterator iter = groupListeneres.iterator(); iter.hasNext();) {
 320  0
             ((GroupListener) iter.next()).suspect( event);
 321   
         }
 322   
     }
 323   
     
 324   
     /**
 325   
      * My message listener implementation.
 326   
      * 
 327   
      * @author no119431
 328   
      *
 329   
      * To change the template for this generated type comment go to
 330   
      * Window>Preferences>Java>Code Generation>Code and Comments
 331   
      */
 332   
     class MyMessageListener implements MessageListener{
 333   
         
 334   
         /* (non-Javadoc)
 335   
          * @see org.jgroups.MessageListener#getState()
 336   
          */
 337  0
         public byte[] getState() {
 338   
             // I'm not interested in this.
 339  0
             return null;
 340   
         }
 341   
 
 342   
         /**
 343   
          * Simply calls the notify method on the main class.
 344   
          * 
 345   
          * @see org.jgroups.MessageListener#receive(org.jgroups.Message)
 346   
          */
 347  8
         public void receive(Message message) {
 348  8
             notifyMessage(message);
 349   
         }
 350   
 
 351   
         /* (non-Javadoc)
 352   
          * @see org.jgroups.MessageListener#setState(byte[])
 353   
          */
 354  0
         public void setState(byte[] arg0) {
 355   
             // I'm not interested in this.
 356   
         }
 357   
 
 358   
     }
 359   
 
 360   
     /**
 361   
      * My Membership Listener implementation.
 362   
      * 
 363   
      * @author no119431
 364   
      *
 365   
      * To change the template for this generated type comment go to
 366   
      * Window>Preferences>Java>Code Generation>Code and Comments
 367   
      */    
 368   
     class MyMembershipListener implements MembershipListener{
 369   
         
 370   
         /* (non-Javadoc)
 371   
          * @see org.jgroups.MembershipListener#block()
 372   
          */
 373  0
         public void block() {
 374   
             // TODO Should i do something here?
 375   
 
 376   
         }
 377   
 
 378   
         /**
 379   
          * Simply calls the notify method on the main class.
 380   
          * 
 381   
          * @see org.jgroups.MembershipListener#suspect(org.jgroups.Address)
 382   
          */
 383  0
         public void suspect(org.jgroups.Address address) {
 384   
             
 385  0
             notifySuspect( address);
 386   
         }
 387   
 
 388   
         /**
 389   
          * Simply calls the notify method on the main class.
 390   
          * 
 391   
          * @see org.jgroups.MembershipListener#viewAccepted(org.jgroups.View)
 392   
          */
 393  34
         public void viewAccepted(View view) {
 394   
             
 395  34
             notifyViewChanged( view);
 396   
         }
 397   
 
 398   
 }
 399   
     /**
 400   
      * @return
 401   
      */
 402  3
     public ChannelFactory getChannelFactory() {
 403  3
         return channelFactory;
 404   
     }
 405   
 
 406   
     /**
 407   
      * @param factory
 408   
      */
 409  3
     public void setChannelFactory(ChannelFactory factory) {
 410  3
         channelFactory = factory;
 411   
     }
 412   
 
 413   
     /**
 414   
      * @return
 415   
      */
 416  3
     public String getChannelProperties() {
 417  3
         return channelProperties;
 418   
     }
 419   
 
 420   
     /**
 421   
      * @param string
 422   
      */
 423  3
     public void setChannelProperties(String string) {
 424  3
         channelProperties = string;
 425   
     }
 426   
     
 427  139
     public Channel getChannel(){
 428   
         
 429  139
         if( channel == null ){
 430  3
             try{
 431  3
                 setChannel( 
 432   
                     getChannelFactory().createChannel( getChannelProperties() ) );
 433   
             }
 434   
             catch(ChannelException e){
 435  0
                 throw new CommunicationException(e);
 436   
             }
 437   
         }
 438   
             
 439  139
         return channel;
 440   
     }
 441   
     
 442  19
     public void setChannel(Channel newChannel){
 443  19
         channel = newChannel;
 444   
     }
 445   
 
 446   
     /**
 447   
      * Returns a copy of the list of current group listeners.
 448   
      * 
 449   
      * Mostly used for testing.
 450   
      * @return
 451   
      */
 452  1
     public List getGroupListeneres() {
 453  1
         return new Vector( groupListeneres );
 454   
     }
 455   
 
 456   
 }
 457