001    /*
002      Copyright (C) 2001-2002 Renaud Pawlak <renaud@aopsys.com>
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 Generaly 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.aspects.distribution;
019    
020    
021    
022    import java.util.*;
023    import org.aopalliance.intercept.ConstructorInvocation;
024    import org.aopalliance.intercept.MethodInvocation;
025    import org.apache.log4j.Logger;
026    import org.objectweb.jac.core.*;
027    import org.objectweb.jac.core.dist.*;
028    import org.objectweb.jac.util.Log;
029    
030    /**
031     * This aspect component implements a simple broadcasting aspect.
032     *
033     * <p>Principles: a broadcaster, located on a given host forwards some
034     * calls to a set of replicas located on remote hosts.
035     *
036     * @see BroadcastingConf
037     * @author Renaud Pawlak
038     */
039    
040    public class BroadcastingAC
041            extends AspectComponent
042            implements BroadcastingConf 
043    {
044        static Logger logger = Logger.getLogger("broadcasting");
045    
046            public void addBroadcaster(
047                    String wrappeeName,
048                    String methods,
049                    String broadcasterHost,
050                    String replicasHost) {
051    
052                    pointcut(
053                            wrappeeName,
054                            ".*",
055                            methods + " && !CONSTRUCTORS",
056                            new BroadcastingWrapper(this, replicasHost),
057                            broadcasterHost,
058                            null);
059            }
060    
061            /**
062             * This wrapper wraps the broadcaster with a wrapping method that
063             * broadcast all the calls to the remote replicas. */
064    
065            public class BroadcastingWrapper extends Wrapper {
066    
067                    Vector replicas = null;
068                    String hostExpr;
069                    boolean doFill = true;
070    
071                    public BroadcastingWrapper(AspectComponent ac, String hostExpr) {
072                            super(ac);
073                            this.hostExpr = hostExpr;
074                    }
075    
076                    public Object invoke(MethodInvocation invocation) throws Throwable {
077                            return broadcast((Interaction) invocation);
078                    }
079    
080                    public Object construct(ConstructorInvocation invocation)
081                            throws Throwable {
082                            throw new Exception("This wrapper does not support constructor wrapping");
083                    }
084    
085                    public void invalidate() {
086                            doFill = true;
087                    }
088    
089                    /**
090                     * Performs a broadcasting. */
091    
092                    public Object broadcast(Interaction interaction) {
093                            if (doFill) {
094                                    replicas =
095                                            Topology.getPartialTopology(hostExpr).getReplicas(
096                                                    interaction.wrappee);
097                                    doFill = false;
098                            }
099                            if (replicas.size() == 0) {
100                                    // none replicas where found, we perform a local call and 
101                                    // will try to get them again on the next call
102                                    doFill = true;
103                                    logger.warn("no replica found, local call performed");
104                                    return proceed(interaction);
105                            }
106                            Object ret = null;
107                            for (int i = 0; i < replicas.size(); i++) {
108                                    ret =
109                                            ((RemoteRef) replicas.get(i)).invoke(
110                                                    interaction.method.getName(),
111                                                    interaction.args);
112                            }
113                            return ret; //proceed(interaction);
114                    }
115    
116            }
117    }