1 package com.tirsen.nanning.samples.rmi; 2 3 import java.util.Collection ; 4 import java.util.Iterator ; 5 6 import com.tirsen.nanning.AspectInstance; 7 import com.tirsen.nanning.Aspects; 8 import com.tirsen.nanning.MixinInstance; 9 import com.tirsen.nanning.attribute.Attributes; 10 import com.tirsen.nanning.config.Aspect; 11 import com.tirsen.nanning.config.AspectSystem; 12 import com.tirsen.nanning.samples.prevayler.Identity; 13 import com.tirsen.nanning.samples.prevayler.Marshaller; 14 15 public class RemoteMarshaller implements Marshaller { 16 private ObjectTable objectTable = new ObjectTable(); 17 private AspectSystem aspectSystem; 18 private ServerConnectionManager connectionManager; 19 20 public static RemoteMarshaller createClientSideMarshaller() { 21 AspectSystem aspectSystem = new AspectSystem(); 22 23 aspectSystem.addAspect(new Aspect() { 24 public void advise(AspectInstance aspectInstance) { 25 } 26 27 public void introduce(AspectInstance aspectInstance) { 28 MixinInstance mixinInstance = new MixinInstance(); 29 mixinInstance.setInterfaceClass(aspectInstance.getClassIdentifier()); 30 aspectInstance.addMixin(mixinInstance); 31 } 32 }); 33 34 RemoteMarshaller remoteMarshaller = new RemoteMarshaller(); 35 36 RemoteAspect aspect = new RemoteAspect(); 37 aspect.setMarshaller(remoteMarshaller); 38 aspectSystem.addAspect(aspect); 39 remoteMarshaller.aspectSystem = aspectSystem; 40 41 return remoteMarshaller; 42 } 43 44 public static RemoteMarshaller createServerSideMarshaller(ServerConnectionManager connectionManager) { 45 RemoteMarshaller remoteMarshaller = new RemoteMarshaller(); 46 remoteMarshaller.connectionManager = connectionManager; 47 return remoteMarshaller; 48 } 49 50 51 private RemoteMarshaller() { 52 } 53 54 public Object unmarshal(Object o) { 55 if (o instanceof Identity) { 56 Identity identity = (Identity) o; 57 Object id = identity.getIdentifier(); 58 if (!objectTable.isIDRegistered(id)) { 59 if (isServerSide()) { 60 throw new RuntimeException ("Did not find remote object on the server side (timeout?): " + o); 62 } 63 Class objectClass = identity.getObjectClass(); 64 Object stub = aspectSystem.newInstance(objectClass); 65 Aspects.getAspectInstance(stub).setTarget(objectClass, identity); 66 return stub; 67 } else { 68 return objectTable.getFromID(id); 70 } 71 } 72 return o; 73 } 74 75 private boolean isServerSide() { 76 return aspectSystem == null; 77 } 78 79 public Object marshal(Object o) { 80 if (o == null) { 81 return null; 82 } 83 84 if (Attributes.hasInheritedAttribute(o.getClass(), "remote")) { 85 if (isRemoteStub(o)) { 86 return getSingleMixinTarget(o); 87 } else { 88 return new RemoteIdentity(Aspects.getAspectInstance(o).getClassIdentifier(), registerID(o), 89 connectionManager); 90 } 91 } else { 92 assert Aspects.isAspectObject(o) ? !isRemoteStub(o) : true 93 : o + " was remote stub but did not have 'remote'-attribute"; 94 assert !(o instanceof RemoteIdentity); 95 } 96 97 return o; 98 } 99 100 Object registerID(Object o) { 101 return objectTable.register(o); 102 } 103 104 public static boolean isRemoteStub(Object o) { 105 return getSingleMixinTarget(o) instanceof RemoteIdentity; 106 } 107 108 private static Object getSingleMixinTarget(Object o) { 109 Collection mixins = Aspects.getAspectInstance(o).getMixins(); 110 Iterator iterator = mixins.iterator(); 111 assert iterator.hasNext() : o + " doesn't have any mixins"; 112 MixinInstance mixinInstance = (MixinInstance) iterator.next(); 113 assert !iterator.hasNext() : "don't support several mixins"; 114 115 Object target = mixinInstance.getTarget(); 116 return target; 117 } 118 119 public void reset() { 120 objectTable.clear(); 121 } 122 } | Popular Tags |