1 4 package com.tc.net.core; 5 6 import com.tc.config.schema.dynamic.ConfigItem; 7 import com.tc.config.schema.dynamic.ConfigItemListener; 8 9 import java.util.ArrayList ; 10 import java.util.Arrays ; 11 import java.util.Iterator ; 12 import java.util.List ; 13 import java.util.NoSuchElementException ; 14 15 public class ConfigBasedConnectionAddressProvider implements ConnectionAddressProvider, ConfigItemListener { 16 17 private final ConfigItem source; 18 19 private int policy; 20 private List currentAddresses = new ArrayList (); 21 private int current = -1; 22 23 public ConfigBasedConnectionAddressProvider(ConfigItem source) { 24 this(ROUND_ROBIN, source); 25 } 26 27 private ConfigBasedConnectionAddressProvider(int policy, ConfigItem source) { 28 this.policy = policy; 29 this.source = source; 30 31 this.source.addListener(this); 32 this.currentAddresses.addAll(Arrays.asList((ConnectionInfo[]) source.getObject())); 33 34 init(); 35 } 36 37 private void init() { 38 switch (policy) { 39 case ROUND_ROBIN: 40 if (currentAddresses.size() == 0) { 41 current = -1; 42 } else if (current < 0 || current >= currentAddresses.size()) { 43 current = 0; 44 } 45 break; 46 case LINEAR: 47 if (currentAddresses.size() == 0) { 48 current = -1; 49 } else if (current < 0) { 50 current = 0; 51 } 52 break; 53 default: 54 throw new AssertionError ("Unimplemented policy for ConnectionAddressProvider !"); 55 } 56 } 57 58 public synchronized void valueChanged(Object oldValue, Object newValue) { 59 ConnectionInfo currentServer; 60 61 try { 62 currentServer = getConnectionInfo(); 63 } catch (NoSuchElementException nsee) { 64 currentServer = null; 65 } 66 67 ConnectionInfo[] newAddresses = (ConnectionInfo[]) this.source.getObject(); 68 this.currentAddresses.clear(); 69 this.currentAddresses.addAll(Arrays.asList(newAddresses)); 70 71 init(); 72 73 Iterator iter = this.currentAddresses.iterator(); 76 int pos = 0; 77 while (iter.hasNext()) { 78 if (currentServer != null && iter.next().equals(currentServer)) { 79 current = pos; 80 break; 81 } 82 ++pos; 83 } 84 } 85 86 private void reinit() { 87 current = -1; 88 init(); 89 } 90 91 public String getHostname() { 92 return getConnectionInfo().getHostname(); 93 } 94 95 public int getPortNumber() { 96 return getConnectionInfo().getPort(); 97 } 98 99 public synchronized int getCount() { 100 return currentAddresses.size(); 101 } 102 103 public synchronized boolean hasNext() { 104 switch (policy) { 105 case ROUND_ROBIN: 106 return currentAddresses.size() > 0; 107 case LINEAR: 108 return currentAddresses.size() > 0 && current < currentAddresses.size() - 1; 109 default: 110 return false; 111 } 112 } 113 114 public synchronized ConnectionInfo getConnectionInfo() { 115 if (current > -1 && current < currentAddresses.size()) { return (ConnectionInfo) currentAddresses.get(current); } 116 throw new NoSuchElementException (); 117 } 118 119 public synchronized ConnectionInfo next() { 120 goNext(); 121 return getConnectionInfo(); 122 } 123 124 private void goNext() { 125 switch (policy) { 126 case ROUND_ROBIN: 127 if (currentAddresses.size() == 0) { 128 current = -1; 129 } else if (current < 0 || current >= currentAddresses.size() - 1) { 130 current = 0; 131 } else { 132 current++; 133 } 134 break; 135 case LINEAR: 136 if (currentAddresses.size() == 0) { 137 current = -1; 138 } else if (current < currentAddresses.size()) { 139 current++; 140 } 141 break; 142 default: 143 throw new AssertionError ("Unimplemented policy for ConnectionAddressProvider !"); 144 } 145 } 146 147 public synchronized void setPolicy(int policy) { 148 switch (policy) { 149 case ROUND_ROBIN: 150 case LINEAR: 151 this.policy = policy; 152 break; 153 default: 154 throw new AssertionError ("Unimplemented policy for ConnectionAddressProvider !"); 155 } 156 reinit(); 157 } 158 159 public String toString() { 160 return "ConnectionAddressProvider(current = " + current + ", policy = " 161 + (policy == ROUND_ROBIN ? "ROUND_ROBIN" : "LINEAR") + ")[" + currentAddresses + "]"; 162 } 163 } 164 | Popular Tags |