KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > object > event > DmiManagerImpl


1 /*
2  * All content copyright (c) 2003-2007 Terracotta, Inc., except as may otherwise be noted in a separate copyright
3  * notice. All rights reserved.
4  */

5 package com.tc.object.event;
6
7 import com.tc.asm.Type;
8 import com.tc.logging.TCLogger;
9 import com.tc.logging.TCLogging;
10 import com.tc.object.ClientObjectManager;
11 import com.tc.object.ObjectID;
12 import com.tc.object.dmi.DmiClassSpec;
13 import com.tc.object.dmi.DmiDescriptor;
14 import com.tc.object.loaders.ClassProvider;
15 import com.tc.object.lockmanager.api.LockLevel;
16 import com.tc.object.logging.RuntimeLogger;
17 import com.tc.util.Assert;
18 import com.tcclient.object.DistributedMethodCall;
19
20 import java.lang.reflect.InvocationTargetException JavaDoc;
21 import java.lang.reflect.Method JavaDoc;
22 import java.util.HashSet JavaDoc;
23 import java.util.Set JavaDoc;
24
25 public class DmiManagerImpl implements DmiManager {
26   private static final TCLogger logger = TCLogging.getLogger(DmiManager.class);
27   private static final String JavaDoc lockName = "@DistributedMethodCall";
28   private static final Object JavaDoc TRUE = new Object JavaDoc();
29
30   private final ClassProvider classProvider;
31   private final ClientObjectManager objMgr;
32   private final RuntimeLogger runtimeLogger;
33   private final ThreadLocal JavaDoc feedBack;
34   private final ThreadLocal JavaDoc nesting;
35
36   public DmiManagerImpl(ClassProvider cp, ClientObjectManager om, RuntimeLogger rl) {
37     Assert.pre(cp != null);
38     Assert.pre(om != null);
39     Assert.pre(rl != null);
40     this.classProvider = cp;
41     this.objMgr = om;
42     this.runtimeLogger = rl;
43     this.feedBack = new ThreadLocal JavaDoc();
44     this.nesting = new ThreadLocal JavaDoc();
45   }
46
47   public boolean distributedInvoke(Object JavaDoc receiver, String JavaDoc method, Object JavaDoc[] params, boolean runOnAllNodes) {
48     if (feedBack.get() != null) { return false; }
49     if (nesting.get() != null) { return false; }
50     nesting.set(TRUE);
51
52     Assert.pre(receiver != null);
53     Assert.pre(method != null);
54     Assert.pre(params != null);
55
56     final String JavaDoc methodName = method.substring(0, method.indexOf('('));
57     final String JavaDoc paramDesc = method.substring(method.indexOf('('));
58     final DistributedMethodCall dmc = new DistributedMethodCall(receiver, params, methodName, paramDesc);
59     if (runtimeLogger.distributedMethodDebug()) runtimeLogger.distributedMethodCall(receiver.getClass().getName(), dmc
60         .getMethodName(), dmc.getParameterDesc());
61     objMgr.getTransactionManager().begin(lockName, LockLevel.CONCURRENT);
62     try {
63       final ObjectID receiverId = objMgr.lookupOrCreate(receiver).getObjectID();
64       final ObjectID dmiCallId = objMgr.lookupOrCreate(dmc).getObjectID();
65       final DmiClassSpec[] classSpecs = getClassSpecs(classProvider, receiver, params);
66       final DmiDescriptor dd = new DmiDescriptor(receiverId, dmiCallId, classSpecs, runOnAllNodes);
67       objMgr.getTransactionManager().addDmiDescriptor(dd);
68       return true;
69     } finally {
70       objMgr.getTransactionManager().commit(lockName);
71     }
72   }
73
74   public void distributedInvokeCommit() {
75     if (feedBack.get() != null) { return; }
76     Assert.pre(nesting.get() != null);
77     nesting.set(null);
78   }
79
80   public void invoke(DmiDescriptor dd) {
81     Assert.pre(dd != null);
82
83     try {
84       checkClassAvailability(classProvider, dd.getClassSpecs());
85     } catch (ClassNotFoundException JavaDoc e) {
86       if (logger.isDebugEnabled()) logger.debug("Ignoring distributed method call", e);
87       return;
88     }
89     DistributedMethodCall dmc;
90     try {
91       dmc = (DistributedMethodCall) objMgr.lookupObject(dd.getDmiCallId());
92     } catch (Throwable JavaDoc e) {
93       if (logger.isDebugEnabled()) logger.debug("Ignoring distributed method call", e);
94       return;
95     }
96     try {
97       if (runtimeLogger.distributedMethodDebug()) runtimeLogger.distributedMethodCall(dmc.getReceiver().getClass()
98           .getName(), dmc.getMethodName(), dmc.getParameterDesc());
99       feedBack.set(TRUE);
100       invoke(dmc);
101     } catch (Throwable JavaDoc e) {
102       runtimeLogger.distributedMethodCallError(dmc.getReceiver().getClass().getName(), dmc.getMethodName(), dmc
103           .getParameterDesc(), e);
104       if (logger.isDebugEnabled()) logger.debug("Ignoring distributed method call", e);
105     } finally {
106       feedBack.set(null);
107     }
108   }
109
110   private static void invoke(DistributedMethodCall dmc) throws IllegalArgumentException JavaDoc, IllegalAccessException JavaDoc,
111       InvocationTargetException JavaDoc {
112     final ClassLoader JavaDoc origContextLoader = Thread.currentThread().getContextClassLoader();
113     Method JavaDoc m = getMethod(dmc);
114     m.setAccessible(true);
115     try {
116       Thread.currentThread().setContextClassLoader(dmc.getReceiver().getClass().getClassLoader());
117       m.invoke(dmc.getReceiver(), dmc.getParameters());
118     } finally {
119       Thread.currentThread().setContextClassLoader(origContextLoader);
120     }
121   }
122
123   private static Method JavaDoc getMethod(DistributedMethodCall dmc) {
124     String JavaDoc methodName = dmc.getMethodName();
125     String JavaDoc paramDesc = dmc.getParameterDesc();
126
127     Class JavaDoc c = dmc.getReceiver().getClass();
128
129     while (c != null) {
130       Method JavaDoc[] methods = c.getDeclaredMethods();
131       for (int i = 0; i < methods.length; i++) {
132         Method JavaDoc m = methods[i];
133         if (!m.getName().equals(methodName)) {
134           continue;
135         }
136         Class JavaDoc[] argTypes = m.getParameterTypes();
137         StringBuffer JavaDoc signature = new StringBuffer JavaDoc("(");
138         for (int j = 0; j < argTypes.length; j++) {
139           signature.append(Type.getDescriptor(argTypes[j]));
140         }
141         signature.append(")");
142         signature.append(Type.getDescriptor(m.getReturnType()));
143         if (signature.toString().equals(paramDesc)) { return m; }
144       }
145
146       c = c.getSuperclass();
147     }
148     throw new RuntimeException JavaDoc("Method " + methodName + paramDesc + " does not exist on this object: "
149                                + dmc.getReceiver());
150   }
151
152   private static void checkClassAvailability(ClassProvider classProvider, DmiClassSpec[] classSpecs)
153       throws ClassNotFoundException JavaDoc {
154     Assert.pre(classSpecs != null);
155     for (int i = 0; i < classSpecs.length; i++) {
156       DmiClassSpec s = classSpecs[i];
157       classProvider.getClassFor(s.getClassName(), s.getClassLoaderDesc());
158     }
159   }
160
161   private static DmiClassSpec[] getClassSpecs(ClassProvider classProvider, Object JavaDoc receiver, Object JavaDoc[] params) {
162     Assert.pre(classProvider != null);
163     Assert.pre(receiver != null);
164     Assert.pre(params != null);
165
166     Set JavaDoc set = new HashSet JavaDoc();
167     set.add(getClassSpec(classProvider, receiver));
168     for (int i = 0; i < params.length; i++) {
169       final Object JavaDoc p = params[i];
170       if (p != null) set.add(getClassSpec(classProvider, p));
171     }
172     DmiClassSpec[] rv = new DmiClassSpec[set.size()];
173     set.toArray(rv);
174     return rv;
175   }
176
177   private static Object JavaDoc getClassSpec(ClassProvider classProvider, Object JavaDoc obj) {
178     Assert.pre(classProvider != null);
179     Assert.pre(obj != null);
180     final String JavaDoc classLoader = classProvider.getLoaderDescriptionFor(obj.getClass());
181     final String JavaDoc className = obj.getClass().getName();
182     return new DmiClassSpec(classLoader, className);
183   }
184
185 }
186
Popular Tags