001    /*
002      Copyright (C) 2001 Lionel Seinturier.
003    
004      This program is free software; you can redistribute it and/or modify
005      it under the terms of the GNU Lesser General Public License as
006      published by the Free Software Foundation; either version 2 of the
007      License, or (at your option) any later version.
008    
009      This program is distributed in the hope that it will be useful,
010      but WITHOUT ANY WARRANTY; without even the implied warranty of
011      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
012      GNU Lesser General Public License for more details.
013    
014      You should have received a copy of the GNU Lesser General Public License
015      along with this program; if not, write to the Free Software
016      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
017    
018    package org.objectweb.jac.core.dist;
019    
020    import org.aopalliance.intercept.ConstructorInvocation;
021    import org.aopalliance.intercept.MethodInvocation;
022    import org.apache.log4j.Logger;
023    import org.objectweb.jac.core.*;
024    import org.objectweb.jac.util.*;
025    
026    /**
027     * StubWrapper is a dynamic client stub for org.objectweb.jac.
028     * Every method called on an object wrapped by such a wrapper
029     * is forwarded to a remote reference.
030     *
031     * The call is blocking.
032     * For non-blocking calls see NonBlockingStubWrapper.
033     *
034     * This a wrapper class.
035     * The invoke method wraps all the methods of a wrappee.
036     *
037     * @see org.objectweb.jac.core.dist.NonBlockingStubWrapper
038     *
039     * @author <a href="http://www-src.lip6.fr/homepages/Lionel.Seinturier/index-eng.html">Lionel Seinturier</a>
040     */
041     
042    public class StubWrapper extends Wrapper {
043        static Logger logger = Logger.getLogger("stub");
044    
045       /**
046        * Construct a new dynamic stub.
047        *
048        * @param remoteRef  the remote reference associated to the stub
049        */
050       
051       public StubWrapper(AspectComponent ac, RemoteRef remoteRef) {
052          super(ac);
053          this.remoteRef = remoteRef;
054       }
055    
056       /**
057        * A more user-friendly constructor.
058        *
059        * @param serverContainer the name of the container where the
060        * server is deployed (can be a regular expression) */
061    
062       public StubWrapper(AspectComponent ac, String serverContainer) {
063          super(ac);
064          this.serverContainer = serverContainer;
065          Topology t = Topology.getPartialTopology( serverContainer );
066          if( t!=null && t.countContainers()>0 ) {
067             this.serverContainer=t.getContainer(0).getName(); 
068          } else {
069             this.serverContainer = serverContainer;
070          }
071       }
072       
073       String serverContainer = null;
074       
075       /** The remote reference attached to this stub */
076    
077       protected RemoteRef remoteRef;
078       
079       
080       /**
081        * The getter method for the remoteRef field.
082        *
083        * @return  the remoteRef field
084        */
085        
086       public RemoteRef getRemoteRef() { return remoteRef; }
087       
088       
089       /**
090        * Forward a call to the remote reference.
091        */
092       
093       public Object _invoke(Interaction interaction) {
094    
095          if( remoteRef == null ) {
096             if( serverContainer == null ) {
097                logger.warn("local call (1) for stub "+interaction.wrappee);
098                return proceed(interaction);
099             }
100             RemoteContainer rc = Topology.get().getFirstContainer(serverContainer);
101             if( rc == null ) {
102                logger.warn("local call (2) for stub "+interaction.wrappee);
103                return proceed(interaction);
104             }
105             remoteRef = rc.bindTo(NameRepository.get().getName(interaction.wrappee));
106             if( remoteRef == null ) {
107                logger.warn("local call (3) for stub "+interaction.wrappee+
108                            " ("+rc+","+serverContainer+")");
109                return proceed(interaction);
110             }
111          }
112    
113          logger.debug(interaction.wrappee + " forwards to the server");
114       
115          /** Invoke the remote reference */
116    
117          return remoteRef.invoke(interaction.method.getName(), interaction.args);
118       }
119    
120       public Object invoke(MethodInvocation invocation) throws Throwable {
121               return _invoke((Interaction) invocation);
122       }
123    
124       public Object construct(ConstructorInvocation invocation)
125               throws Throwable {
126               throw new Exception("Wrapper "+this+" does not support construction interception.");
127       }
128    
129    }
130    
131    
132    
133    
134    
135    
136