org/objectweb/proactive/core/body/proxy/UniversalBodyProxy.java

00001 /* 
00002  * ################################################################
00003  * 
00004  * ProActive: The Java(TM) library for Parallel, Distributed, 
00005  *            Concurrent computing with Security and Mobility
00006  * 
00007  * Copyright (C) 1997-2007 INRIA/University of Nice-Sophia Antipolis
00008  * Contact: proactive@objectweb.org
00009  * 
00010  * This library is free software; you can redistribute it and/or
00011  * modify it under the terms of the GNU Lesser General Public
00012  * License as published by the Free Software Foundation; either
00013  * version 2.1 of the License, or any later version.
00014  *  
00015  * This library is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018  * Lesser General Public License for more details.
00019  * 
00020  * You should have received a copy of the GNU Lesser General Public
00021  * License along with this library; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
00023  * USA
00024  *  
00025  *  Initial developer(s):               The ProActive Team
00026  *                        http://www.inria.fr/oasis/ProActive/contacts.html
00027  *  Contributor(s): 
00028  * 
00029  * ################################################################
00030  */ 
00031 package org.objectweb.proactive.core.body.proxy;
00032 
00033 import java.lang.reflect.Constructor;
00034 import java.lang.reflect.InvocationTargetException;
00035 import java.util.Collection;
00036 import java.util.Vector;
00037 
00038 import org.apache.log4j.Logger;
00039 import org.objectweb.proactive.Active;
00040 import org.objectweb.proactive.Body;
00041 import org.objectweb.proactive.ProActive;
00042 import org.objectweb.proactive.core.Constants;
00043 import org.objectweb.proactive.core.ProActiveException;
00044 import org.objectweb.proactive.core.body.AbstractBody;
00045 import org.objectweb.proactive.core.body.LocalBodyStore;
00046 import org.objectweb.proactive.core.body.MetaObjectFactory;
00047 import org.objectweb.proactive.core.body.UniversalBody;
00048 import org.objectweb.proactive.core.body.future.Future;
00049 import org.objectweb.proactive.core.body.future.FutureProxy;
00050 import org.objectweb.proactive.core.exceptions.manager.ExceptionHandler;
00051 import org.objectweb.proactive.core.gc.GarbageCollector;
00052 import org.objectweb.proactive.core.mop.ConstructorCall;
00053 import org.objectweb.proactive.core.mop.ConstructorCallExecutionFailedException;
00054 import org.objectweb.proactive.core.mop.ConstructorCallImpl;
00055 import org.objectweb.proactive.core.mop.MethodCall;
00056 import org.objectweb.proactive.core.node.Node;
00057 import org.objectweb.proactive.core.node.NodeException;
00058 import org.objectweb.proactive.core.node.NodeFactory;
00059 import org.objectweb.proactive.core.runtime.ProActiveRuntime;
00060 import org.objectweb.proactive.core.runtime.ProActiveRuntimeImpl;
00061 import org.objectweb.proactive.core.util.log.Loggers;
00062 import org.objectweb.proactive.core.util.log.ProActiveLogger;
00063 import org.objectweb.proactive.ext.security.exceptions.RenegotiateSessionException;
00064 
00065 
00066 public class UniversalBodyProxy extends AbstractBodyProxy
00067     implements java.io.Serializable {
00068     protected static Logger logger = ProActiveLogger.getLogger(Loggers.BODY);
00069 
00070     // note that we do not want to serialize this member but rather handle
00071     // the serialization by ourselve
00072     protected transient UniversalBody universalBody;
00073     protected transient boolean isLocal;
00074 
00075     private static ThreadLocal<Collection<UniversalBodyProxy>> incomingReferences = new ThreadLocal<Collection<UniversalBodyProxy>>() {
00076         protected synchronized Collection<UniversalBodyProxy> initialValue() {
00077             return new Vector<UniversalBodyProxy>();
00078         }
00079     };
00080     
00081     //
00082     // -- CONSTRUCTORS -----------------------------------------------
00083     //
00084 
00088     public UniversalBodyProxy() {
00089     }
00090 
00102     public UniversalBodyProxy(ConstructorCall constructorCall,
00103         Object[] parameters) throws ProActiveException {
00104         Object p0 = parameters[0];
00105 
00106         // Determines whether the body is local or remote
00107         if (p0 instanceof UniversalBody) {
00108             // This is simple connection to an existant local body
00109             this.universalBody = (UniversalBody) p0;
00110             this.bodyID = universalBody.getID();
00111             isLocal = LocalBodyStore.getInstance().getLocalBody(bodyID) != null;
00112             if (logger.isDebugEnabled()) {
00113                 //logger.debug("UniversalBodyProxy created from UniversalBody bodyID="+bodyID+" isLocal="+isLocal);
00114             }
00115         } else {
00116             // instantiate the body locally or remotely
00117             Class bodyClass = Constants.DEFAULT_BODY_CLASS;
00118             Node node = (Node) p0;
00119 
00120             //added lines--------------------------
00121             //ProActiveRuntime part = node.getProActiveRuntime();
00122             //added lines----------------------------
00123             Active activity = (Active) parameters[1];
00124             MetaObjectFactory factory = (MetaObjectFactory) parameters[2];
00125             String jobID = (String) parameters[3];
00126             Class[] argsClass = new Class[] {
00127                     ConstructorCall.class, String.class, Active.class,
00128                     MetaObjectFactory.class, String.class
00129                 };
00130             Object[] args = new Object[] {
00131                     constructorCall, node.getNodeInformation().getURL(),
00132                     activity, factory, jobID
00133                 };
00134 
00135             //added lines--------------------------
00136             //Object[] args = new Object[] { constructorCall, node.getNodeInformation().getURL(), activity, factory };
00137             //added lines--------------------------
00138             ConstructorCall bodyConstructorCall = buildBodyConstructorCall(bodyClass,
00139                     argsClass, args);
00140             if (NodeFactory.isNodeLocal(node)) {
00141                 // the node is local
00142                 //added line -------------------------
00143                 //if (RuntimeFactory.isRuntimeLocal(part)){
00144                 //added line -------------------------
00145                 this.universalBody = createLocalBody(bodyConstructorCall,
00146                         constructorCall, node);
00147                 isLocal = true;
00148             } else {
00149                 this.universalBody = createRemoteBody(bodyConstructorCall, node);
00150                 //added line -------------------------
00151                 //this.universalBody = createRemoteBody(bodyConstructorCall, part , node);
00152                 //added line -------------------------
00153                 isLocal = false;
00154             }
00155             this.bodyID = universalBody.getID();
00156             if (logger.isDebugEnabled()) {
00157                 //logger.debug("UniversalBodyProxy created from constructorCall bodyID="+bodyID+" isLocal="+isLocal);
00158             }
00159         }
00160 
00161         if (GarbageCollector.isBuildingTopology()) {
00162                 ((AbstractBody)ProActive.getBodyOnThis()).updateReference(this);
00163         }
00164     }
00165 
00166     //
00167     // -- PUBLIC METHODS -----------------------------------------------
00168     //
00169     public boolean equals(Object o) {
00170         if (!(o instanceof UniversalBodyProxy)) {
00171             return false;
00172         }
00173 
00174         UniversalBodyProxy proxy = (UniversalBodyProxy) o;
00175         return universalBody.equals(proxy.universalBody);
00176     }
00177 
00178     public int hashCode() {
00179         return universalBody.hashCode();
00180     }
00181 
00182     //
00183     // -- implements BodyProxy interface -----------------------------------------------
00184     //
00185     public UniversalBody getBody() {
00186         return universalBody;
00187     }
00188 
00189     //
00190     // -- PROTECTED METHODS -----------------------------------------------
00191     //
00192     protected UniversalBody createLocalBody(
00193         ConstructorCall bodyConstructorCall,
00194         ConstructorCall reifiedObjectConstructorCall, Node node)
00195         throws ProActiveException {
00196         try {
00197             reifiedObjectConstructorCall.makeDeepCopyOfArguments();
00198 
00199             //The node is local, so is the proActiveRuntime
00200             // acessing it direclty avoids to get a copy of the body
00201             ProActiveRuntime part = ProActiveRuntimeImpl.getProActiveRuntime();
00202 
00203             //return (UniversalBody) bodyConstructorCall.execute();
00204             //---------------------added lines--------------------------
00205             //                  if (logger.isDebugEnabled()) {
00206             //                                          logger.debug("LocalBodyProxy created using " + body + " from ConstructorCall");
00207             //                  }
00208             return part.createBody(node.getNodeInformation().getName(),
00209                 bodyConstructorCall, true);
00210             //---------------------added lines------------------------------
00211         } catch (ConstructorCallExecutionFailedException e) {
00212             throw new ProActiveException(e);
00213         } catch (InvocationTargetException e) {
00214             throw new ProActiveException(e.getTargetException());
00215         } catch (java.io.IOException e) {
00216             throw new ProActiveException("Error in the copy of the arguments of the constructor",
00217                 e);
00218         }
00219     }
00220 
00221     protected UniversalBody createRemoteBody(
00222         ConstructorCall bodyConstructorCall, Node node)
00223         throws ProActiveException {
00224         try {
00225             ProActiveRuntime part = node.getProActiveRuntime();
00226 
00227             //if (logger.isDebugEnabled()) {
00228             //            //logger.debug("UniversalBodyProxy.createRemoteBody bodyClass="+bodyClass+"  node="+node);
00229             //}
00230             //return node.createBody(bodyConstructorCall);
00231             //--------------added lines
00232             if (logger.isDebugEnabled()) {
00233                 logger.debug("RemoteBodyProxy created bodyID=" + bodyID +
00234                     " from ConstructorCall");
00235             }
00236             return part.createBody(node.getNodeInformation().getName(),
00237                 bodyConstructorCall, false);
00238             //--------------added lines
00239         } catch (ConstructorCallExecutionFailedException e) {
00240             throw new ProActiveException(e);
00241         } catch (java.lang.reflect.InvocationTargetException e) {
00242             throw new ProActiveException(e);
00243         } catch (NodeException e) {
00244             throw new ProActiveException(e);
00245         }
00246     }
00247 
00248     protected void sendRequest(MethodCall methodCall, Future future)
00249         throws java.io.IOException, RenegotiateSessionException {
00250         // Determines the body that is at the root of the subsystem from which the
00251         // call was sent.
00252         // It is always true that the body that issued the request (and not the body
00253         // that is the target of the call) and this BodyProxy are in the same
00254         // address space because being a local representative for something remote
00255         // is what the proxy is all about. This is why we know that the table that
00256         // can be accessed by using a static methode has this information.
00257         ExceptionHandler.addRequest(methodCall, (FutureProxy) future);
00258         try {
00259             sendRequest(methodCall, future,
00260                 LocalBodyStore.getInstance().getCurrentThreadBody());
00261         } catch (java.io.IOException ioe) {
00262             if (future != null) {
00263                 /* (future == null) happens on one-way calls */
00264                 ExceptionHandler.addResult((FutureProxy) future);
00265             }
00266             throw ioe;
00267         }
00268     }
00269 
00270     protected void sendRequest(MethodCall methodCall, Future future,
00271         Body sourceBody)
00272         throws java.io.IOException, RenegotiateSessionException {
00273         // TODO if component request and shortcut : update body ref
00274         // Now we check whether the reference to the remoteBody has changed i.e the body has migrated
00275         // Maybe we could use some optimisation here
00276         //UniqueID id = universalBody.getID();
00277         UniversalBody newBody = sourceBody.checkNewLocation(bodyID);
00278         if (newBody != null) {
00279             universalBody = newBody;
00280             isLocal = LocalBodyStore.getInstance().getLocalBody(bodyID) != null;
00281         }
00282         sourceBody.getFuturePool().registerDestination(universalBody);
00283         if (isLocal) {
00284             // Replaces the effective arguments with a deep copy
00285             // Only do this if the body is local
00286             // For remote bodies, this is automatically handled by the RMI stub
00287             methodCall.makeDeepCopyOfArguments();
00288         }
00289         sendRequestInternal(methodCall, future, sourceBody);
00290         sourceBody.getFuturePool().removeDestination();
00291     }
00292 
00293     protected void sendRequestInternal(MethodCall methodCall, Future future,
00294         Body sourceBody)
00295         throws java.io.IOException, RenegotiateSessionException {
00296         sourceBody.sendRequest(methodCall, future, universalBody);
00297     }
00298 
00299     //
00300     // -- PRIVATE METHODS -----------------------------------------------
00301     //
00302     private ConstructorCall buildBodyConstructorCall(Class bodyClass,
00303         Class[] argsClass, Object[] args) throws ProActiveException {
00304         // Determines the constructor of the body object: it is the constructor that
00305         // has only one argument, this argument being of type ConstructorCall
00306         try {
00307             Constructor cstr = bodyClass.getConstructor(argsClass);
00308 
00309             // A word of explanation: here we have two nested ConstructorCall objects:
00310             // 'bodyConstructorCall' is the reification of the construction of the body,
00311             // which contains another ConstructorCall object that represents the reification
00312             // of the construction of the reified object itself.
00313             return new ConstructorCallImpl(cstr, args);
00314         } catch (NoSuchMethodException e) {
00315             throw new ProActiveException("Class " + bodyClass.getName() +
00316                 " has no constructor matching ", e);
00317         }
00318     }
00319 
00320     public boolean isLocal() {
00321         return this.isLocal;
00322     }
00323 
00324     //
00325     // -- SERIALIZATION -----------------------------------------------
00326     //
00327     private void writeObject(java.io.ObjectOutputStream out)
00328         throws java.io.IOException {
00329         if (this.universalBody == null) {
00330             out.writeObject(null);
00331         } else {
00332             out.writeObject(universalBody.getRemoteAdapter());
00333         }
00334     }
00335 
00336     public static Collection<UniversalBodyProxy> getIncomingReferences() {
00337         Collection<UniversalBodyProxy> res = incomingReferences.get();
00338         incomingReferences.set(new Vector<UniversalBodyProxy>());
00339         return res;
00340     }
00341 
00342     private void readObject(java.io.ObjectInputStream in)
00343         throws java.io.IOException, ClassNotFoundException {
00344         Body localBody = LocalBodyStore.getInstance().getLocalBody(bodyID);
00345 
00346         // Thread.dumpStack();
00347         if (logger.isDebugEnabled()) {
00348             logger.debug("Local body is " + localBody);
00349         }
00350         if (localBody != null) {
00351             // the body is local
00352             universalBody = localBody;
00353             in.readObject();
00354             isLocal = true;
00355         } else {
00356             // the body is not local
00357             universalBody = (UniversalBody) in.readObject();
00358             isLocal = false;
00359         }
00360         if (logger.isDebugEnabled()) {
00361             logger.debug("universalBody is " + universalBody);
00362         }
00363         
00364         if (GarbageCollector.isBuildingTopology()) {
00365                 incomingReferences.get().add(this);
00366         }
00367     }
00368 }

Generated on Mon Jan 22 15:16:06 2007 for ProActive by  doxygen 1.5.1