1 7 package org.jboss.cache.aop; 8 9 import org.jboss.aop.advice.Interceptor; 10 import org.jboss.aop.joinpoint.FieldReadInvocation; 11 import org.jboss.aop.joinpoint.FieldWriteInvocation; 12 import org.jboss.aop.joinpoint.Invocation; 13 import org.jboss.aop.joinpoint.MethodInvocation; 14 import org.jboss.cache.Fqn; 15 import org.jboss.logging.Logger; 16 17 import java.io.Externalizable ; 18 import java.io.ObjectInput ; 19 import java.io.ObjectOutput ; 20 import java.lang.reflect.Field ; 21 import java.lang.reflect.Method ; 22 import java.util.Iterator ; 23 24 30 31 public class CacheInterceptor implements Interceptor 32 { 33 protected static Logger log_ = Logger.getLogger(CacheInterceptor.class); 34 TreeCacheAop cache; 35 Fqn fqn; 36 CachedType type; 37 boolean checkSerialization; 38 39 static Method writeExternal, readExternal; 40 41 static 42 { 43 try { 44 writeExternal = 45 Externalizable .class.getMethod("writeExternal", 46 new Class []{ObjectOutput .class}); 47 readExternal = 48 Externalizable .class.getMethod("readExternal", 49 new Class []{ObjectInput .class}); 50 } catch (Exception e) { 51 e.printStackTrace(); 52 } 53 } 54 55 public CacheInterceptor(TreeCacheAop cache, Fqn fqn, CachedType type) 56 { 57 this.cache = cache; 58 this.fqn = fqn; 59 this.type = type; 60 checkSerialization = 61 !WriteReplaceable.class.isAssignableFrom(type.getType()); 62 } 63 64 public String getName() 65 { 66 return "CacheInterceptor on [" + fqn + "]"; 67 } 68 69 public Object invoke(Invocation invocation) throws Throwable 70 { 71 if (invocation instanceof FieldWriteInvocation) { 72 checkCacheConsistency(); 73 FieldWriteInvocation fieldInvocation = 74 (FieldWriteInvocation) invocation; 75 Field field = fieldInvocation.getField(); 76 77 if( !CachedType.isNonReplicatable(field)) { 79 80 CachedType fieldType = cache.getCachedType(field.getType()); 81 82 Object value = fieldInvocation.getValue(); 83 if (fieldType.isImmediate()) { 84 cache.put(fqn, field.getName(), value); 85 } else { 86 cache.putObject(new Fqn(fqn, field.getName()), value); 88 } 89 } 90 91 } else if (invocation instanceof FieldReadInvocation) { 92 checkCacheConsistency(); 93 FieldReadInvocation fieldInvocation = 94 (FieldReadInvocation) invocation; 95 Field field = fieldInvocation.getField(); 96 if( !CachedType.isNonReplicatable(field)) { 98 99 CachedType fieldType = cache.getCachedType(field.getType()); 100 Object result; 101 if (fieldType.isImmediate()) { 102 result = cache.get(fqn, field.getName()); 103 } else { 104 result = cache.getObject(new Fqn(fqn, field.getName())); 106 } 107 108 if(result != null) 112 return result; 113 else { 114 Object value = invocation.getTargetObject(); 116 if(value == null || field.get(value) == null) return null; 119 else { 120 if(log_.isDebugEnabled()) { 121 log_.debug("invoke(): Node on fqn: " +fqn + " has obviously been evicted. Will need to reconstruct it"); 122 } 123 124 cache.putObject(fqn, value); 125 } 126 } 127 } 128 } else if (checkSerialization) { 129 MethodInvocation methodInvocation = (MethodInvocation) invocation; 130 Method method = methodInvocation.getMethod(); 131 132 if (method != null 133 && method.getName().equals("writeReplace") 134 && method.getReturnType().equals(Object .class) 135 && method.getParameterTypes().length == 0) { 136 137 beforeSerialization(invocation.getTargetObject()); 138 } else if (method == writeExternal) { 139 Object target = methodInvocation.getTargetObject(); 140 beforeSerialization(target); 141 } 142 } 143 144 return invocation.invokeNext(); 145 146 } 147 148 protected void checkCacheConsistency() throws Exception 149 { 150 if (this != cache.peek(fqn, AOPInstance.KEY)) { 151 new RuntimeException ("Cache inconsistency: Outdated AOPInstance"); 152 } 153 } 154 155 public void beforeSerialization(Object target) throws Exception 156 { 157 158 for (Iterator i = type.getFields().iterator(); i.hasNext();) { 160 Field field = (Field ) i.next(); 161 CachedType fieldType = cache.getCachedType(field.getType()); 162 Object value = null; 163 if (fieldType.isImmediate()) { 164 value = cache.get(fqn, field.getName()); 165 } else { 166 value = cache.getObject(new Fqn(fqn, field.getName())); 169 } 170 field.set(target, value); 172 } 173 } 174 175 boolean isChildOf(Fqn parentFqn) 176 { 177 return fqn.isChildOf(parentFqn); 178 } 179 180 Fqn getFqn() 181 { 182 return fqn; 183 } 184 185 void setFqn(Fqn fqn) 186 { 187 this.fqn = fqn; 188 } 189 190 } 191 | Popular Tags |