1 22 package org.jboss.tm.remoting; 23 24 import java.io.Externalizable ; 25 import java.io.IOException ; 26 import java.io.ObjectInput ; 27 import java.io.ObjectOutput ; 28 import java.lang.reflect.InvocationHandler ; 29 import java.lang.reflect.Method ; 30 import java.rmi.RemoteException ; 31 import java.util.ArrayList ; 32 import java.util.List ; 33 34 import org.jboss.remoting.CannotConnectException; 35 import org.jboss.remoting.Client; 36 import org.jboss.remoting.InvalidConfigurationException; 37 import org.jboss.remoting.InvokerLocator; 38 import org.jboss.tm.remoting.interfaces.Coordinator; 39 import org.jboss.tm.remoting.interfaces.RecoveryCoordinator; 40 import org.jboss.tm.remoting.interfaces.Resource; 41 import org.jboss.tm.remoting.interfaces.Synchronization; 42 import org.jboss.tm.remoting.interfaces.Terminator; 43 import org.jboss.tm.remoting.interfaces.TransactionFactory; 44 import org.jboss.tm.remoting.server.DistributedTransactionManager; 45 46 53 public class ClientInvocationHandler 54 implements InvocationHandler , Externalizable 55 { 56 static final long serialVersionUID = 2253923354553253502L; 57 58 60 public static final char TRANSACTION_FACTORY = 'F'; 61 public static final char COORDINATOR = 'C'; 62 public static final char TERMINATOR = 'T'; 63 public static final char RESOURCE = 'R'; 64 public static final char RECOVERY_COORDINATOR = 'V'; 65 public static final char SYNCHRONIZATION = 'S'; 66 67 69 private char interfaceCode; 70 private long targetObjectId; 71 private InvokerLocator[] locators; 72 private Client client; private String stringRepresentation; 74 75 77 78 public ClientInvocationHandler() 79 { 80 } 81 82 87 public ClientInvocationHandler(Class interf, InvokerLocator[] locators) 88 throws Exception 89 { 90 this(interf, 0, locators); 91 } 92 93 98 public ClientInvocationHandler(Class interf, 99 long targetObjectId, 100 InvokerLocator[] locators) 101 throws Exception 102 { 103 this(getInterfaceCode(interf), targetObjectId, locators); 104 } 105 106 111 public ClientInvocationHandler(char interfaceCode, InvokerLocator[] locators) 112 throws Exception 113 { 114 this(interfaceCode, 0, locators); 115 } 116 117 122 public ClientInvocationHandler(char interfaceCode, 123 long targetObjectId, 124 InvokerLocator[] locators) 125 throws Exception 126 { 127 if (interfaceCode != TRANSACTION_FACTORY 128 && interfaceCode != COORDINATOR 129 && interfaceCode != TERMINATOR 130 && interfaceCode != RESOURCE 131 && interfaceCode != RECOVERY_COORDINATOR 132 && interfaceCode != SYNCHRONIZATION) 133 throw new IllegalArgumentException (); 134 135 if (locators.length == 0) 136 throw new IllegalArgumentException (); 137 138 this.interfaceCode = interfaceCode; 139 this.targetObjectId = targetObjectId; 140 this.locators = locators; 141 } 142 143 145 149 Class getClientInterface() { 151 switch (interfaceCode) 152 { 153 case TRANSACTION_FACTORY: 154 return TransactionFactory.class; 155 case COORDINATOR: 156 return Coordinator.class; 157 case TERMINATOR: 158 return Terminator .class; 159 case RESOURCE: 160 return Resource.class; 161 case RECOVERY_COORDINATOR: 162 return RecoveryCoordinator.class; 163 case SYNCHRONIZATION: 164 return Synchronization.class; 165 } 166 throw new RuntimeException ("Illegal value in field interfaceCode"); 167 } 168 169 173 private static char getInterfaceCode(Class interf) 174 { 175 if (interf == TransactionFactory.class) 176 return TRANSACTION_FACTORY; 177 else if (interf == Coordinator.class) 178 return COORDINATOR; 179 else if (interf == Terminator .class) 180 return TERMINATOR; 181 else if (interf == Resource.class) 182 return RESOURCE; 183 else if (interf == RecoveryCoordinator.class) 184 return RECOVERY_COORDINATOR; 185 else if (interf == Synchronization.class) 186 return SYNCHRONIZATION; 187 else 188 throw new IllegalArgumentException ("argument is not a DTM interface"); 189 } 190 191 193 198 public Object invoke(Object proxy, Method method, Object [] args) 199 throws Throwable 200 { 201 Exception savedException = null; 202 203 if (method.getDeclaringClass() == Object .class) 204 { 205 String methodName = method.getName(); 206 207 if (methodName.equals("toString")) 208 return this.toString(); 209 else if (methodName.equals("hashCode")) 210 return new Integer (this.toString().hashCode()); 211 else if (methodName.equals("equals")) 212 return new Boolean (this.toString().equals(args[0].toString())); 213 } 214 215 if (client != null) 216 { 217 try 219 { 220 return client.invoke(new Invocation(targetObjectId, method, args)); 221 } 222 catch (CannotConnectException e) 223 { 224 client = null; 225 } 226 227 } 228 229 Invocation invocation = new Invocation(targetObjectId, method, args); 234 for (int i = 0; i < locators.length; i++) 235 { 236 try 237 { 238 client = new Client(locators[i], 239 DistributedTransactionManager.SUBSYSTEM); 240 return client.invoke(invocation); 241 } 242 catch (CannotConnectException e) 243 { 244 client = null; 245 savedException = e; 246 } 247 catch (InvalidConfigurationException e) 248 { 249 client = null; 250 savedException = e; 251 } 252 } 253 throw new RemoteException (savedException.getClass().getName(), 254 savedException); 255 } 256 257 259 263 public void readExternal(ObjectInput in) 264 throws IOException , ClassNotFoundException 265 { 266 this.interfaceCode = in.readChar(); 267 this.targetObjectId = in.readLong(); 268 short len = in.readShort(); 269 if (len < 1) 270 throw new IOException ("ObjectInput does not contain a valid " + 271 "ClientInvocationHandler"); 272 this.locators = new InvokerLocator[len]; 273 for (int i = 0; i < len; i++) 274 { 275 this.locators[i] = new InvokerLocator(in.readUTF()); 276 } 277 this.client = null; 278 } 279 280 284 public void writeExternal(ObjectOutput out) throws IOException 285 { 286 out.writeChar(interfaceCode); 287 out.writeLong(targetObjectId); 288 out.writeShort(locators.length); 289 for (int i = 0; i < locators.length; i++) 290 { 291 out.writeUTF(locators[i].getLocatorURI()); 292 } 293 } 294 295 297 309 public String toString() 310 { 311 if (stringRepresentation == null) 312 stringRepresentation = interfaceCode + 313 Long.toHexString(targetObjectId) + 314 ',' + locators[0].getLocatorURI(); 315 for (int i = 1; i < locators.length; i++) 316 { 317 stringRepresentation += '|' + locators[i].getLocatorURI(); 318 } 319 return stringRepresentation; 320 } 321 322 326 public static ClientInvocationHandler fromString(String s) 327 throws Exception 328 { 329 String locatorURI; 330 InvokerLocator locator; 331 332 int oidEndIndex = s.indexOf(','); 333 if (oidEndIndex == -1) 334 throw new IllegalArgumentException (); 335 336 String oidString = s.substring(1, oidEndIndex); 337 int uriStartIndex = oidEndIndex + 1; 338 int uriEndIndex = s.indexOf('|', uriStartIndex); 339 340 if (uriEndIndex == -1) 341 { 342 locatorURI = s.substring(uriStartIndex); 344 locator = new InvokerLocator(locatorURI); 345 return new ClientInvocationHandler(s.charAt(0), 346 Long.parseLong(oidString, 16), 347 new InvokerLocator[] { locator }); 348 } 349 else 350 { 351 List locatorList = new ArrayList (); 353 while (uriEndIndex != -1) 354 { 355 locatorURI = s.substring(uriStartIndex, uriEndIndex); 356 locator = new InvokerLocator(locatorURI); 357 locatorList.add(locator); 358 uriStartIndex = uriEndIndex + 1; 359 uriEndIndex = s.indexOf('|', uriStartIndex); 360 } 361 locatorURI = s.substring(uriStartIndex); 362 locator = new InvokerLocator(locatorURI); 363 locatorList.add(locator); 364 InvokerLocator[] locators = 365 (InvokerLocator[]) locatorList.toArray(new InvokerLocator[0]); 366 return new ClientInvocationHandler(s.charAt(0), 367 Long.parseLong(oidString, 16), 368 locators); 369 } 370 } 371 372 } 373 | Popular Tags |