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 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 class implements the core protocol for a strong 029 * consistency that is based on a pull strategy. 030 * 031 * <p>On contrary to the <code>StrongPushConsistencyWrapper</code>, 032 * this protocol pulls the data from the other replicas. Indeed, each 033 * time a data is read and is not locally available, it is fetched 034 * from the known replicas.<p> 035 * 036 * @see StrongPushConsistencyWrapper 037 * 038 * @author <a href="http://cedric.cnam.fr/~pawlak/index-english.html">Renaud Pawlak</a> 039 */ 040 041 public class StrongPullConsistencyWrapper extends ConsistencyWrapper { 042 static Logger logger = Logger.getLogger("consistency"); 043 044 String hosts = null; 045 046 /** 047 * A friendly constructor for a pull consistency wrapper. 048 * 049 * @param hosts a regular expression that defines the host where 050 * the consistency protocol is installed */ 051 052 public StrongPullConsistencyWrapper(AspectComponent ac, String hosts) { 053 super(ac); 054 this.hosts = hosts; 055 knownReplicas = null; 056 } 057 058 /** An empty constructor for the Consistency class. */ 059 public StrongPullConsistencyWrapper(AspectComponent ac) { 060 super(ac); 061 } 062 063 /** 064 * This wrapping method first try to use the wrappee to get the 065 * result of the read method.<p> 066 * 067 * If this result is null or if an exception occurs, it considers 068 * that the read information was not locally present and tries to 069 * fetch it from the replicas it knows (recursivelly all the 070 * replicas are finally asked). If none of the replica returns a 071 * value, it returns null or throws an exception. 072 * 073 * @return the value returned by the wrapped read method */ 074 075 public Object whenRead(Interaction interaction) { 076 077 Object ret = null; 078 079 ret = proceed(interaction); 080 081 logger.debug("Pull knownReplicas = "+knownReplicas); 082 083 if (ret == null) { 084 085 if (knownReplicas != null) { 086 Collaboration c = Collaboration.get(); 087 Vector asked_replicas = (Vector)c.getAttribute(visitedReplicas); 088 if (asked_replicas == null) { 089 asked_replicas = (Vector)c.addAttribute( 090 visitedReplicas, new Vector()); 091 } 092 093 //System.out.println ( "########### " + notified_replicas ); 094 try { 095 Vector new_ar = new Vector(); 096 RemoteRef cur_replica = RemoteRef.create( 097 NameRepository.get().getName(interaction.wrappee), 098 interaction.wrappee); 099 100 for (int i = 0; i < knownReplicas.size(); i++) { 101 if ( (! asked_replicas.contains( knownReplicas.get(i) ) ) && 102 (! ((RemoteRef)knownReplicas.get(i)).getRemCont().isLocal()) ) { 103 104 Vector kr = new Vector(knownReplicas); 105 kr.remove(knownReplicas.get(i)); 106 new_ar.clear(); 107 new_ar.addAll(asked_replicas); 108 new_ar.addAll(kr); 109 new_ar.add(cur_replica); 110 c.addAttribute(visitedReplicas, new_ar); 111 112 logger.debug("(strong pull) read event on " + 113 interaction.wrappee + ":" + 114 interaction.method + ":" + 115 ((RemoteRef)knownReplicas.get(i)).getRemCont().getName()); 116 ret = ((RemoteRef)knownReplicas.get(i)).invokeRoleMethod( 117 "acceptRemoteRead", 118 new Object[] { null, 119 new Object[] { interaction.method, 120 interaction.args } } ); 121 if (ret != null) { 122 break; 123 } 124 } 125 } 126 } finally { 127 c.addAttribute(visitedReplicas, null); 128 } 129 } 130 } 131 return ret; 132 } 133 134 /** 135 * Try to read the method asked by <code>whenRead</code>.<p> 136 * 137 * The data is :<p> 138 * <ul><pre> 139 * data[0] = the read method name string 140 * data[1] = an array that contains the arguments of the read method 141 * </pre></ul> 142 * 143 * @param remoteReplica the replica that received the read event 144 * @param data the read event data 145 * @return the return value of the <code>data[0]</code> method*/ 146 147 public Object acceptRemoteRead(Wrappee wrappee, RemoteRef remoteReplica, 148 Object[] data) { 149 logger.debug("(strong pull) remote read event on " + 150 wrappee + ":" + (String)data[0]); 151 return ClassRepository.get().getClass(wrappee).getMethod((String)data[0]).invoke( 152 wrappee , (Object[])data[1] ); 153 } 154 155 156 }