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 }