001 /* 002 Copyright (C) 2001 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 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.aspects.distribution.consistency; 019 020 import java.util.*; 021 import org.apache.log4j.Logger; 022 import org.objectweb.jac.core.*; 023 import org.objectweb.jac.core.dist.*; 024 import org.objectweb.jac.core.rtti.ClassRepository; 025 import org.objectweb.jac.util.*; 026 027 /** 028 * This wrapper implements a client-server consistency protocol. 029 * 030 * <p>It is a special consistency protocol since the wrappee acts as a 031 * pure client (a stub) for its known replicas.<p> 032 * 033 * @author <a href="http://cedric.cnam.fr/~pawlak/index-english.html">Renaud Pawlak</a> */ 034 035 public class ClientServerConsistencyWrapper extends ConsistencyWrapper { 036 static Logger logger = Logger.getLogger("consistency"); 037 038 String hosts = null; 039 040 /** 041 * A friendly constructor for a client-server consistency wrapper. 042 * 043 * @param hosts a regular expression that defines the host where 044 * the server is located 045 */ 046 public ClientServerConsistencyWrapper(AspectComponent ac, String hosts) { 047 super(ac); 048 knownReplicas = null; 049 this.hosts = hosts; 050 } 051 052 /** An empty constructor for the Consistency class. */ 053 public ClientServerConsistencyWrapper(AspectComponent ac) { 054 super(ac); 055 } 056 057 /** 058 * Forwards the call to the server(s).<p> 059 * 060 * Do not call the replica except if we do not know any server (in 061 * this case, we are a server).<p> 062 * 063 * @return the value returned by the server */ 064 065 public Object whenCall(Interaction interaction) { 066 067 if( knownReplicas == null ) { 068 knownReplicas = Topology.getPartialTopology(hosts).getReplicas(interaction.wrappee); 069 } 070 071 if(knownReplicas != null && knownReplicas.size() > 0 && 072 (! ((RemoteRef)knownReplicas.get(0)).getRemCont().isLocal()) ) { 073 logger.debug("(client-server) call event on " + 074 NameRepository.get().getName(interaction.wrappee) + 075 ":" + interaction.method + ":" + 076 ((RemoteRef)knownReplicas.get(0)).getRemCont().getName()); 077 Object ret = ((RemoteRef)knownReplicas.get(0)).invokeRoleMethod( 078 "acceptRemoteCall", 079 new Object[] { null, new Object[] { interaction.method, interaction.args } } 080 ); 081 return ret; 082 } else { 083 /* we do not know any replica, so we are the server... */ 084 return proceed(interaction); 085 } 086 } 087 088 /** 089 * Calls the method on the server. 090 * 091 * @param remoteReplica the client remote reference 092 * @param data the name and the parameters of the server method 093 */ 094 095 public Object acceptRemoteCall(Wrappee wrappee, RemoteRef remoteReplica, 096 Object[] data) { 097 logger.debug("(client-server) remote call event on " + 098 NameRepository.get().getName(wrappee) + 099 ":" + (String)data[0] + ":" + 100 Arrays.asList((Object[])data[1])); 101 return ClassRepository.get().getClass(wrappee).getMethod((String)data[0]).invoke( 102 wrappee , (Object[])data[1] ); 103 } 104 }