1 package com.tirsen.nanning.samples.prevayler; 2 3 import java.io.Serializable ; 4 import java.util.Date ; 5 import java.util.Set ; 6 import java.util.HashSet ; 7 import java.lang.reflect.AccessibleObject ; 8 9 import com.tirsen.nanning.Aspects; 10 11 public class IdentifyingMarshaller implements Marshaller, Serializable { 12 static final long serialVersionUID = 7285806267400465332L; 13 14 public Object marshal(Object o) { 15 if (PrevaylerUtils.isPrimitive(o)) { 16 return o; 17 18 } else if (PrevaylerUtils.isStatefulService(o.getClass())) { 19 assert o instanceof Serializable : "Stateful services must be serializable"; 20 return o; 21 22 } else if (PrevaylerUtils.isStatelessService(o.getClass())) { 23 return new Identity(o.getClass(), Aspects.getAspectInstance(o).getClassIdentifier()); 24 25 } else if (PrevaylerUtils.isEntity(o.getClass())) { 26 if (getSystem().hasObjectID(o)) { 27 return new Identity(Aspects.getAspectInstance(o).getClassIdentifier(), new Long (getSystem().getObjectID(o))); 28 } else { 29 30 return o; 31 } 32 33 } else { 34 return o; 35 } 36 } 37 38 public Object unmarshal(Object o) { 39 if (PrevaylerUtils.isPrimitive(o)) { 40 return o; 41 42 } else if (o instanceof Identity) { 43 return resolve((Identity) o); 44 45 } else if (PrevaylerUtils.isEntity(o.getClass())) { 46 if (!getSystem().hasObjectID(o)) { 47 registerObjectIDsRecursive(o); 48 } 49 return o; 50 51 } else { 52 return o; 53 } 54 } 55 56 private IdentifyingSystem getSystem() { 57 Object system = CurrentPrevayler.getSystem(); 58 assert system instanceof IdentifyingSystem : "I need an identifying system to work"; 59 return (IdentifyingSystem) system; 60 } 61 62 private Object resolve(Identity identity) { 63 Class objectClass = identity.getObjectClass(); 64 if (PrevaylerUtils.isStatelessService(objectClass)) { 65 return Aspects.getCurrentAspectFactory().newInstance((Class ) identity.getIdentifier()); 66 } 67 if (PrevaylerUtils.isEntity(objectClass)) { 68 long oid = ((Long ) identity.getIdentifier()).longValue(); 69 assert getSystem().isIDRegistered(oid) : "object of type " + Aspects.getRealClass(objectClass) + " had invalid object id " + oid; 70 return getSystem().getObjectWithID(oid); 71 } 72 throw new IllegalArgumentException ("Can't resolve objects of " + objectClass); 73 } 74 75 private void registerObjectIDsRecursive(final Object objectToRegister) { 76 final IdentifyingSystem system = getSystem(); 77 final Set registeredObjects = new HashSet (); 78 79 ObjectGraphVisitor.visit(objectToRegister, new ObjectGraphVisitor() { 80 protected void visit(Object o) { 81 if (o instanceof AccessibleObject ) { 82 return; 83 } 84 if (o instanceof Date ) { 85 return; 86 } 87 if (PrevaylerUtils.isPrimitive(o)) { 88 return; 89 } 90 if (!registeredObjects.contains(o) && PrevaylerUtils.isEntity(o.getClass())) { 91 assert !system.hasObjectID(o) : "you're mixing objects in prevayler with objects outside, this will lead to unpredictable results, " + 92 "so I've banished that sort of behaviour with this assert here" + 93 "(the object that was inside prevayler was " + o + " the object that was outside was " + objectToRegister + ")"; 94 95 system.registerObjectID(o); 96 registeredObjects.add(o); 97 } 98 99 100 if (Aspects.isAspectObject(o)) { 101 Object [] targets = Aspects.getTargets(o); 102 for (int i = 0; i < targets.length; i++) { 103 super.visit(targets[i]); 104 } 105 } else { 106 super.visit(o); 107 } 108 } 109 }); 110 } 111 } 112 | Popular Tags |