KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > cache > aop > CacheInterceptor


1 /*
2  * JBoss, the OpenSource J2EE webOS
3  *
4  * Distributable under LGPL license.
5  * See terms of license at gnu.org.
6  */

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 JavaDoc;
18 import java.io.ObjectInput JavaDoc;
19 import java.io.ObjectOutput JavaDoc;
20 import java.lang.reflect.Field JavaDoc;
21 import java.lang.reflect.Method JavaDoc;
22 import java.util.Iterator JavaDoc;
23
24 /**
25  * Created: Sat Apr 26 10:35:01 2003
26  *
27  * @author Harald Gliebe
28  * @author Ben Wang
29  */

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 JavaDoc writeExternal, readExternal;
40
41    static
42    {
43       try {
44          writeExternal =
45                Externalizable JavaDoc.class.getMethod("writeExternal",
46                      new Class JavaDoc[]{ObjectOutput JavaDoc.class});
47          readExternal =
48                Externalizable JavaDoc.class.getMethod("readExternal",
49                      new Class JavaDoc[]{ObjectInput JavaDoc.class});
50       } catch (Exception JavaDoc 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 JavaDoc getName()
65    {
66       return "CacheInterceptor on [" + fqn + "]";
67    }
68
69    public Object JavaDoc invoke(Invocation invocation) throws Throwable JavaDoc
70    {
71       if (invocation instanceof FieldWriteInvocation) {
72          checkCacheConsistency();
73          FieldWriteInvocation fieldInvocation =
74                (FieldWriteInvocation) invocation;
75          Field JavaDoc field = fieldInvocation.getField();
76
77          // Only if this field is replicatable
78
if( !CachedType.isNonReplicatable(field)) {
79
80             CachedType fieldType = cache.getCachedType(field.getType());
81
82             Object JavaDoc value = fieldInvocation.getValue();
83             if (fieldType.isImmediate()) {
84                cache.put(fqn, field.getName(), value);
85             } else {
86                //cache.putObject(((Fqn)fqn.clone()).add(field.getName()), value);
87
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 JavaDoc field = fieldInvocation.getField();
96          // Only if this field is replicatable
97
if( !CachedType.isNonReplicatable(field)) {
98
99             CachedType fieldType = cache.getCachedType(field.getType());
100             Object JavaDoc result;
101             if (fieldType.isImmediate()) {
102                result = cache.get(fqn, field.getName());
103             } else {
104                //result = cache.getObject(((Fqn)fqn.clone()).add(field.getName()));
105
result = cache.getObject(new Fqn(fqn, field.getName()));
106             }
107
108             // if result is null, we need to make sure the in-memory reference is null
109
// as well. If it is not, then we know this one is null because it has
110
// been evicted. Will need to reconstruct it
111
if(result != null)
112                return result;
113             else {
114                // TODO There is a chance of recursive loop here if caller tries to print out obj that will trigger the fieldRead interception.
115
Object JavaDoc value = invocation.getTargetObject();
116                // TODO Need to handle the modifiers transient, final, and static fields here
117
if(value == null || field.get(value) == null) // if both are null, we know this is null as well.
118
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 JavaDoc method = methodInvocation.getMethod();
131
132          if (method != null
133                && method.getName().equals("writeReplace")
134                && method.getReturnType().equals(Object JavaDoc.class)
135                && method.getParameterTypes().length == 0) {
136
137             beforeSerialization(invocation.getTargetObject());
138          } else if (method == writeExternal) {
139             Object JavaDoc target = methodInvocation.getTargetObject();
140             beforeSerialization(target);
141          }
142       }
143
144       return invocation.invokeNext();
145
146    }
147
148    protected void checkCacheConsistency() throws Exception JavaDoc
149    {
150       if (this != cache.peek(fqn, AOPInstance.KEY)) {
151          new RuntimeException JavaDoc("Cache inconsistency: Outdated AOPInstance");
152       }
153    }
154
155    public void beforeSerialization(Object JavaDoc target) throws Exception JavaDoc
156    {
157
158       // fill objects
159
for (Iterator JavaDoc i = type.getFields().iterator(); i.hasNext();) {
160          Field JavaDoc field = (Field JavaDoc) i.next();
161          CachedType fieldType = cache.getCachedType(field.getType());
162          Object JavaDoc value = null;
163          if (fieldType.isImmediate()) {
164             value = cache.get(fqn, field.getName());
165          } else {
166             // value = removeObject(fqn+TreeCache.SEPARATOR+field.getName());
167
//value = cache.getObject(((Fqn)fqn.clone()).add(field.getName()));
168
value = cache.getObject(new Fqn(fqn, field.getName()));
169          }
170          // System.out.println("Setting field " + field.getName() + "[" + field.getDeclaringClass() + "] of "+ target.getClass() + " to " + value);
171
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