00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 package org.objectweb.proactive.core.body.proxy;
00032
00033 import java.lang.reflect.Type;
00034 import java.lang.reflect.TypeVariable;
00035 import java.util.Collections;
00036 import java.util.HashSet;
00037 import java.util.Set;
00038
00039 import org.apache.log4j.Level;
00040 import org.apache.log4j.Logger;
00041 import org.objectweb.proactive.Body;
00042 import org.objectweb.proactive.core.Constants;
00043 import org.objectweb.proactive.core.ProActiveRuntimeException;
00044 import org.objectweb.proactive.core.UniqueID;
00045 import org.objectweb.proactive.core.body.future.Future;
00046 import org.objectweb.proactive.core.body.future.FutureProxy;
00047 import org.objectweb.proactive.core.exceptions.manager.NFEManager;
00048 import org.objectweb.proactive.core.exceptions.proxy.FutureCreationException;
00049 import org.objectweb.proactive.core.exceptions.proxy.ProxyNonFunctionalException;
00050 import org.objectweb.proactive.core.exceptions.proxy.SendRequestCommunicationException;
00051 import org.objectweb.proactive.core.mop.MOP;
00052 import org.objectweb.proactive.core.mop.MOPException;
00053 import org.objectweb.proactive.core.mop.MethodCall;
00054 import org.objectweb.proactive.core.mop.MethodCallExecutionFailedException;
00055 import org.objectweb.proactive.core.mop.Proxy;
00056 import org.objectweb.proactive.core.mop.StubObject;
00057 import org.objectweb.proactive.core.util.log.Loggers;
00058 import org.objectweb.proactive.core.util.log.ProActiveLogger;
00059 import org.objectweb.proactive.ext.security.exceptions.RenegotiateSessionException;
00060
00061
00062 public abstract class AbstractBodyProxy extends AbstractProxy
00063 implements BodyProxy, java.io.Serializable {
00064
00065
00066
00067 private static Logger syncCallLogger = ProActiveLogger.getLogger(Loggers.SYNC_CALL);
00068
00069
00070
00071
00072 protected UniqueID bodyID;
00073 protected Integer cachedHashCode = null;
00074
00075
00076
00077
00078 public AbstractBodyProxy() {
00079 }
00080
00081 AbstractBodyProxy(UniqueID bodyID) {
00082 this.bodyID = bodyID;
00083 }
00084
00085
00086
00087
00088
00089
00090
00091 public UniqueID getBodyID() {
00092 return bodyID;
00093 }
00094
00095
00096
00097
00098
00114 public Object reify(MethodCall methodCall) throws Throwable {
00115 Object cachedMethodResult = checkOptimizedMethod(methodCall);
00116 if (cachedMethodResult != null) {
00117 return cachedMethodResult;
00118 }
00119 return invokeOnBody(methodCall);
00120 }
00121
00122
00123
00124
00125
00126
00127 private static boolean isToString(MethodCall methodCall) {
00128 return (methodCall.getNumberOfParameter() == 0) &&
00129 "toString".equals(methodCall.getName());
00130 }
00131
00132 private static Set<String> loggedSyncCalls = Collections.synchronizedSet(new HashSet<String>());
00133
00134 private Object invokeOnBody(MethodCall methodCall)
00135 throws Exception, RenegotiateSessionException, Throwable {
00136
00137 try {
00138 if (isOneWayCall(methodCall)) {
00139 reifyAsOneWay(methodCall);
00140 return null;
00141 }
00142 String reason = methodCall.getSynchronousReason();
00143 if (reason == null) {
00144 return reifyAsAsynchronous(methodCall);
00145 }
00146 if (!isToString(methodCall) &&
00147 syncCallLogger.isEnabledFor(Level.DEBUG)) {
00148 String msg = "[WARNING: synchronous call] All calls to the method below are synchronous "
00149 + "(not an error, but may lead to performance issues or deadlocks):"
00150 + System.getProperty("line.separator") +
00151 methodCall.getReifiedMethod()
00152 + System.getProperty("line.separator") +
00153 "They are synchronous for the following reason: " + reason;
00154 ;
00155 if (loggedSyncCalls.add(msg)) {
00156 syncCallLogger.debug(msg);
00157 }
00158 }
00159 return reifyAsSynchronous(methodCall);
00160 } catch (MethodCallExecutionFailedException e) {
00161 throw new ProActiveRuntimeException(e.getMessage(),
00162 e.getTargetException());
00163 }
00164 }
00165
00166
00167
00168 private Object checkOptimizedMethod(MethodCall methodCall)
00169 throws Exception, RenegotiateSessionException, Throwable {
00170 if (methodCall.getName().equals("equals") &&
00171 (methodCall.getNumberOfParameter() == 1)) {
00172 Object arg = methodCall.getParameter(0);
00173 if (MOP.isReifiedObject(arg)) {
00174 Proxy proxy = ((StubObject) arg).getProxy();
00175 if (proxy instanceof AbstractBodyProxy) {
00176 return new Boolean(bodyID.equals(
00177 ((AbstractBodyProxy) proxy).bodyID));
00178 }
00179 }
00180 return new Boolean(false);
00181 }
00182
00183 if (methodCall.getName().equals("hashCode") &&
00184 (methodCall.getNumberOfParameter() == 0)) {
00185 if (cachedHashCode == null) {
00186 return cachedHashCode = (Integer) invokeOnBody(methodCall);
00187 } else {
00188 return cachedHashCode;
00189 }
00190 }
00191
00192 return null;
00193 }
00194
00198 protected void reifyAsOneWay(MethodCall methodCall)
00199 throws Exception, RenegotiateSessionException {
00200 try {
00201 sendRequest(methodCall, null);
00202 } catch (java.io.IOException e) {
00203
00204
00205
00206 ProxyNonFunctionalException nfe = new SendRequestCommunicationException(
00207 "Exception occured in reifyAsOneWay while sending request for methodcall = " +
00208 methodCall.getName(), e);
00209
00210 NFEManager.fireNFE(nfe, this);
00211 }
00212 }
00213
00214
00215
00216
00217
00218 public static class VoidFuture {
00219 public VoidFuture() {
00220 }
00221 }
00222
00223 protected Object reifyAsAsynchronous(MethodCall methodCall)
00224 throws Exception, RenegotiateSessionException {
00225 StubObject futureobject = null;
00226
00227
00228 try {
00229 Class returnType = null;
00230 Type t = methodCall.getReifiedMethod().getGenericReturnType();
00231 if (t instanceof TypeVariable) {
00232 returnType = methodCall.getGenericTypesMapping().get(t);
00233 } else {
00234 returnType = methodCall.getReifiedMethod().getReturnType();
00235 }
00236
00237
00238
00239 if (returnType.equals(java.lang.Void.TYPE)) {
00240
00241 futureobject = (StubObject) MOP.newInstance(VoidFuture.class,
00242 null, Constants.DEFAULT_FUTURE_PROXY_CLASS_NAME, null);
00243 } else {
00244 futureobject = (StubObject) MOP.newInstance(returnType, null,
00245 Constants.DEFAULT_FUTURE_PROXY_CLASS_NAME, null);
00246 }
00247 } catch (MOPException e) {
00248
00249 ProxyNonFunctionalException nfe = new FutureCreationException(
00250 "Exception occured in reifyAsAsynchronous while creating future for methodcall = " +
00251 methodCall.getName(), e);
00252
00253 NFEManager.fireNFE(nfe, this);
00254 } catch (ClassNotFoundException e) {
00255
00256 ProxyNonFunctionalException nfe = new FutureCreationException(
00257 "Exception occured in reifyAsAsynchronous while creating future for methodcall = " +
00258 methodCall.getName(), e);
00259
00260 NFEManager.fireNFE(nfe, this);
00261 }
00262
00263
00264 FutureProxy fp = (FutureProxy) (futureobject.getProxy());
00265 fp.setCreatorID(bodyID);
00266 fp.setOriginatingProxy(this);
00267
00268 try {
00269 sendRequest(methodCall, fp);
00270 } catch (java.io.IOException e) {
00271
00272
00273
00274 ProxyNonFunctionalException nfe = new SendRequestCommunicationException(
00275 "Exception occured in reifyAsAsynchronous while sending request for methodcall = " +
00276 methodCall.getName(), e);
00277
00278 NFEManager.fireNFE(nfe, this);
00279 }
00280
00281
00282 return futureobject;
00283 }
00284
00285 protected Object reifyAsSynchronous(MethodCall methodCall)
00286 throws Throwable, Exception, RenegotiateSessionException {
00287
00288 FutureProxy fp = FutureProxy.getFutureProxy();
00289 fp.setCreatorID(bodyID);
00290 fp.setOriginatingProxy(this);
00291
00292 try {
00293 sendRequest(methodCall, fp);
00294 } catch (java.io.IOException e) {
00295
00296
00297
00298 ProxyNonFunctionalException nfe = new SendRequestCommunicationException(
00299 "Exception occured in reifyAsSynchronous while sending request for methodcall = " +
00300 methodCall.getName(), e);
00301
00302 NFEManager.fireNFE(nfe, this);
00303 }
00304
00305
00306 if (fp.getRaisedException() != null) {
00307 throw fp.getRaisedException();
00308 } else {
00309 return fp.getResult();
00310 }
00311 }
00312
00313 protected abstract void sendRequest(MethodCall methodCall, Future future)
00314 throws java.io.IOException, RenegotiateSessionException;
00315
00316 protected abstract void sendRequest(MethodCall methodCall, Future future,
00317 Body sourceBody)
00318 throws java.io.IOException, RenegotiateSessionException;
00319 }