KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jac > aspects > distribution > consistency > ConsistencyWrapper


1 /*
2   Copyright (C) 2001-2002 Renaud Pawlak <renaud@aopsys.com>
3
4   This program is free software; you can redistribute it and/or modify
5   it under the terms of the GNU Lesser General Public License as
6   published by the Free Software Foundation; either version 2 of the
7   License, or (at your option) any later version.
8
9   This program is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12   GNU Lesser General Public License for more details.
13
14   You should have received a copy of the GNU Lesser General Public License
15   along with this program; if not, write to the Free Software
16   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */

17
18 package org.objectweb.jac.aspects.distribution.consistency;
19
20 import java.util.*;
21 import org.aopalliance.intercept.ConstructorInvocation;
22 import org.aopalliance.intercept.MethodInvocation;
23 import org.apache.log4j.Logger;
24 import org.objectweb.jac.core.*;
25 import org.objectweb.jac.core.dist.*;
26 import org.objectweb.jac.core.rtti.ClassRepository;
27 import org.objectweb.jac.util.Log;
28
29 /**
30  * This wrapper class is the base class for all the consistency
31  * wrappers that implement a consistency protocol.
32  *
33  * <p>By default it does nothing and provides no consistency at all
34  * between the replicas. A consistency programmer should define the
35  * wrapping and role method to implement a specific consistency
36  * protocol.<p>
37  *
38  * @author <a HREF="http://cedric.cnam.fr/~pawlak/index-english.html">Renaud Pawlak</a>
39  */

40
41 public class ConsistencyWrapper extends Wrapper {
42     static Logger logger = Logger.getLogger("consistency");
43
44     /** Storage for known replicas. */
45     protected Vector knownReplicas = new Vector();
46
47     /** The replicas type. */
48     Class JavaDoc type = null;
49
50     /** The read method names. */
51     String JavaDoc[] readMethods = null;
52
53     /** The write method names. */
54     String JavaDoc[] writeMethods = null;
55
56     /** The call method names. */
57     String JavaDoc[] callMethods = null;
58
59     String JavaDoc hosts = null;
60
61     /** Visited sites global attribute name. */
62     static protected String JavaDoc visitedReplicas = "visitedReplicas";
63
64     static {
65         Collaboration.setGlobal(visitedReplicas);
66     }
67
68     /** Use to indicate that you need all the methods. */
69     public static String JavaDoc ALL_METHODS = "ALL";
70     /** Use to indicate that you need all the modifiers. */
71     public static String JavaDoc ALL_MODIFIERS = "ALL_MODIFIERS";
72     /** Use to indicate that you need all the getters. */
73     public static String JavaDoc ALL_GETTERS = "ALL_GETTERS";
74
75     /**
76      * Default constructor. */

77
78     public ConsistencyWrapper(AspectComponent ac) {
79         super(ac);
80         this.knownReplicas = null;
81     }
82
83     /**
84      * Contructor for initialization.
85      *
86      * @param type the type of the wrappee
87      * @param readMethods the methods that read the wrappee's state
88      * @param writeMethods the methods that write the wrappee's state
89      * @param callMethods the stateless methods */

90
91     public ConsistencyWrapper(
92         AspectComponent ac,
93         Class JavaDoc type,
94         String JavaDoc[] readMethods,
95         String JavaDoc[] writeMethods,
96         String JavaDoc[] callMethods,
97         String JavaDoc hosts) {
98         super(ac);
99         this.type = type;
100         setReadMethods(readMethods);
101         setWriteMethods(writeMethods);
102         setCallMethods(callMethods);
103         this.hosts = hosts;
104     }
105
106     /**
107      * Wraps a wrappee with a consistency wrapper. */

108
109     public static void wrap(
110         Wrappee wrappee,
111         Class JavaDoc wrapperClass,
112         String JavaDoc[] readMethods,
113         String JavaDoc[] writeMethods,
114         String JavaDoc[] callMethods,
115         String JavaDoc hosts) {
116         ConsistencyWrapper wrapper = null;
117         try {
118             wrapper =
119                 (ConsistencyWrapper) wrapperClass
120                     .getConstructor(new Class JavaDoc[] { AspectComponent.class })
121                     .newInstance(new Object JavaDoc[] { null });
122         } catch (Exception JavaDoc e) {
123             e.printStackTrace();
124             return;
125         }
126         wrapper.type = wrappee.getClass();
127         wrapper.setReadMethods(readMethods);
128         wrapper.setWriteMethods(writeMethods);
129         wrapper.setCallMethods(callMethods);
130         wrapper.hosts = hosts;
131         // TODO: consitency reengineering.
132
//Wrapping.wrap(wrappee, wrapper, "whenRead", readMethods);
133
//Wrapping.wrap(wrappee, wrapper, "whenWrite", writeMethods);
134
//Wrapping.wrap(wrappee, wrapper, "whenCall", callMethods);
135
}
136
137     /**
138      * Add a replica to the knowledge graph.<p>
139      *
140      * The way the member is added
141      * to the knowledge graph depends on the knowledge graph.
142      *
143      * @param newReplica the reference on the replica to add
144      */

145
146     public void addMember(RemoteRef newReplica) {
147
148         String JavaDoc[][] wrapped_methods =
149             new String JavaDoc[][] { readMethods, writeMethods, callMethods };
150         String JavaDoc[] wrapping_methods =
151             new String JavaDoc[] { "whenRead", "whenWrite", "whenCall" };
152         Class JavaDoc wrapper_type = getClass();
153         ConsistencyWrapper wrapper = null;
154
155         try {
156
157             wrapper = (ConsistencyWrapper) wrapper_type.newInstance();
158
159             if (wrapper == null) {
160                 throw new InstantiationException JavaDoc();
161             }
162
163             wrapper.setReadMethods(readMethods);
164             wrapper.setWriteMethods(writeMethods);
165             wrapper.setCallMethods(callMethods);
166
167         } catch (Exception JavaDoc e) {
168             e.printStackTrace();
169         }
170
171         wrapper.addKnownReplica(newReplica);
172
173         newReplica.invoke(
174             "wrap",
175             new Object JavaDoc[] { wrapper, wrapping_methods, wrapped_methods });
176
177         whenBindingNewReplica(newReplica);
178
179         /* newReplica.invoke(
180            "invokeRoleMethod",
181            new Object[] {
182               "whenNewReplicaBounded",
183               new Object[] {
184                  null,
185               }
186            }
187            );*/

188
189     }
190
191     /**
192      * Invalidates the topology.
193      *
194      * <p>When this method is called, the next consistency protocol run
195      * will recalculate the known replica with the new topology. */

196
197     public void invalidateTopology() {
198         knownReplicas = null;
199     }
200
201     /**
202      * Calculates the known replicas with the topology and the host
203      * expression. */

204
205     void calculateKnownReplicas(Wrappee wrappee) {
206         logger.debug("calculing known replicas for " + wrappee);
207         knownReplicas = Topology.getPartialTopology(hosts).getReplicas(wrappee);
208         logger.debug("result for known replicas="+ knownReplicas
209                 + "(on topology " + Topology.getPartialTopology(hosts) + ")");
210     }
211
212     /**
213      * This method is called when new member is bounded to the
214      * replication group.
215      *
216      * <p>It is typically used to initialize (in a push manner) the new
217      * member state with the data that need to be replicated. By
218      * default, this method does nothing.
219      *
220      * @param newReplica the replica that is beeing added */

221
222     public void whenBindingNewReplica(RemoteRef newReplica) {
223     }
224
225     /**
226      * This method is called on the new member when the binding is
227      * finished.
228      *
229      * <p>It is typically used to initialize (in a pull manner)
230      * the new member state with the data that need to be
231      * replicated. By default, this method does nothing.
232      *
233      * @param remoteReplica the replica that has just been bounded
234      */

235
236     public void whenNewReplicaBounded(RemoteRef remoteReplica) {
237     }
238
239     /**
240      * Returns the visited replicas global attribute of the
241      * collaboration.
242      *
243      * @return the name of the attribute
244      */

245
246     public String JavaDoc getVisitedReplicas() {
247         return visitedReplicas;
248     }
249
250     /**
251      * Returns a string representation of the wrapper.
252      *
253      * @return a string representation of the wrapper
254      */

255
256     public String JavaDoc toString() {
257         if (knownReplicas == null)
258             return "Consistency wrapper, no known replicas";
259         else
260             return "Consistency wrapper, known replicas = " + knownReplicas;
261     }
262
263     /**
264      * Set the read method names (methods that read the replica
265      * state).
266      *
267      * @param readMethods the names of the read methods */

268
269     public void setReadMethods(String JavaDoc[] readMethods) {
270         this.readMethods = expandMethods(readMethods);
271     }
272
273     /**
274      * Set the write method names (methods that change the replica
275      * state).
276      *
277      * @param writeMethods the names of the write methods
278      */

279
280     public void setWriteMethods(String JavaDoc[] writeMethods) {
281         this.writeMethods = expandMethods(writeMethods);
282     }
283
284     /**
285      * Set the call method names (methods that neither write or read
286      * the replica state).
287      *
288      * @param callMethods the names of the call methods
289      */

290
291     public void setCallMethods(String JavaDoc[] callMethods) {
292         this.callMethods = expandMethods(callMethods);
293     }
294
295     /**
296      * The getter method for the known replicas.
297      *
298      * <p>The known replicas of a consistency wrapper are remote
299      * references on other member of the replication group. With this
300      * information, the consistency wrapper can implement consistency
301      * protocols. The most usual schemes are to be aware of all the
302      * replicas of the group (see for instance
303      * <code>StrongPushConsistencyWrapper</code>) or to be aware of ony
304      * one replica (see for instance
305      * <code>ClientServerConsistencyWrapper</code>.
306      *
307      * @return a set of references on the known replicas */

308
309     public Vector getKnownReplicas() {
310         return knownReplicas;
311     }
312
313     /**
314      * Adds a known replica.
315      *
316      * @param newReplica the known replica to add
317      */

318     public void addKnownReplica(RemoteRef newReplica) {
319         knownReplicas.add(newReplica);
320     }
321
322     /**
323      * The get method for the consistency wrapper actual type.<p>
324      *
325      * @return the class of the wrapper */

326
327     public Class JavaDoc getConsistencyWrapperType() {
328         return getClass();
329     }
330
331     /**
332      * The setter method for the known replicas.<p>
333      *
334      * The known replicas of a consistency wrapper are remote
335      * references on other member of the replication group. With this
336      * information, the consistency wrapper can implement consistency
337      * protocols. The most usual schemes are to be aware of all the
338      * replicas of the group (see for instance
339      * <code>StrongPushConsistencyWrapper</code>) or to be aware of ony
340      * one replica (see for instance
341      * <code>ClientServerConsistencyWrapper</code>.<p>
342      *
343      * @param knownReplicas the new known replicas */

344
345     public void setKnownReplicas(Vector knownReplicas) {
346         this.knownReplicas = knownReplicas;
347     }
348
349     /**
350      * This wrapping method must be defined to implement a given
351      * builtin consistency protocol and must wrap the replica methods
352      * that need to be consistent with the other replicas.<p>
353      *
354      * It should not wrap a method that is allready wrapped by a
355      * <code>WhenWrite</code> or <code>WhenRead</code> method.<p>
356      *
357      * Default: do nothing and call the replica.<p>
358      *
359      * @return by default the wrapped method return value
360      * @see #acceptRemoteCall(RemoteRef,Object[]) */

361
362     public Object JavaDoc whenCall(Interaction interaction) {
363         return proceed(interaction);
364     }
365
366     /**
367      * This wrapping method must be defined to implement a given
368      * builtin consistency protocol and must wrap all the replicas
369      * methods that provoque a change in this replica state.<p>
370      *
371      * Default: do nothing and call the replica.<p>
372      *
373      * @return by default the wrapped method return value
374      * @see #acceptRemoteWrite(Wrappee,RemoteRef,Object[]) */

375
376     public Object JavaDoc whenWrite(Interaction interaction) {
377         return proceed(interaction);
378     }
379
380     /**
381      * This wrapping method must be defined to implement a given
382      * builtin consistency protocol and must wrap all the replica
383      * methods that read the replica state.<p>
384      *
385      * Default: do nothing and call the replica.<p>
386      *
387      * @return by default the wrapped method return value
388      * @see #acceptRemoteRead(Wrappee,RemoteRef,Object[]) */

389
390     public Object JavaDoc whenRead(Interaction interaction) {
391         return proceed(interaction);
392     }
393
394     /**
395      * This role method can called by the <code>whenCall</code>
396      * wrapping method of a remote replica.<p>
397      *
398      * By overloading this method, the programmer can implement
399      * specific consistency protocols.<p>
400      *
401      * Default: do nothing.<p>
402      *
403      * @param remoteReplica expected to be a reference on the remote
404      * replica that recieved the call event
405      * @param data the data transmittedd by <code>whenCall</code>
406      * @return null by default
407      * @see #whenCall(Interaction) */

408
409     public Object JavaDoc acceptRemoteCall(RemoteRef remoteReplica, Object JavaDoc[] data) {
410         return null;
411     }
412
413     /**
414      * This role method can called by the <code>whenWrite</code>
415      * wrapping method of a remote replica.<p>
416      *
417      * By overloading this method, the programmer can implement
418      * specific consistency protocols.<p>
419      *
420      * Default: do nothing.<p>
421      *
422      * @param remoteReplica expected to be a reference on the remote
423      * replica that recieved the write event
424      * @param data the data transmittedd by <code>whenWrite</code>
425      * @return null by default
426      * @see #whenWrite(Interaction) */

427
428     public Object JavaDoc acceptRemoteWrite(
429         Wrappee wrappee,
430         RemoteRef remoteReplica,
431         Object JavaDoc[] data) {
432         return null;
433     }
434
435     /**
436      * This role method can called by the <code>whenRead</code>
437      * wrapping method of a remote replica.<p>
438      *
439      * By overloading this method, the programmer can implement
440      * specific consistency protocols.<p>
441      *
442      * Default: do nothing.<p>
443      *
444      * @param remoteReplica expected to be a reference on the remote
445      * replica that recieved the read event
446      * @param data the data transmittedd by <code>whenRead</code>
447      * @return null by default
448      * @see #whenRead(Interaction) */

449
450     public Object JavaDoc acceptRemoteRead(
451         Wrappee wrappee,
452         RemoteRef remoteReplica,
453         Object JavaDoc[] data) {
454         return null;
455     }
456
457     /**
458      * Construct a real methods array with an array that can contain
459      * consistency specific strings (like the one that indicates that
460      * we need all the modifiers).
461      *
462      * @param methods a set of methods to expand (can contain
463      * ALL_METHODS, ALL_MODIFIERS, and ALL_GETTERS keywords)
464      * @return a set of methods where the keywords have been expanded
465      * with the corresponding method of the type
466      */

467     protected String JavaDoc[] expandMethods(String JavaDoc[] methods) {
468         if (methods == null)
469             return null;
470         Vector newVM = new Vector();
471         for (int i = 0; i < methods.length; i++) {
472             if (methods[i].equals(ALL_METHODS)) {
473                 newVM.addAll(
474                     Arrays.asList(ClassRepository.getMethodsName(type)));
475             } else if (methods[i].equals(ALL_MODIFIERS)) {
476                 newVM.addAll(
477                     Arrays.asList(ClassRepository.getModifiersNames(type)));
478             } else if (methods[i].equals(ALL_GETTERS)) {
479                 newVM.addAll(
480                     Arrays.asList(ClassRepository.getGettersNames(type)));
481             } else {
482                 newVM.add(methods[i]);
483             }
484         }
485         String JavaDoc[] newMethods = new String JavaDoc[newVM.size()];
486         for (int i = 0; i < newMethods.length; i++) {
487             newMethods[i] = (String JavaDoc) newVM.get(i);
488         }
489         return newMethods;
490     }
491
492     /* (non-Javadoc)
493      * @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
494      */

495     public Object JavaDoc invoke(MethodInvocation invocation) throws Throwable JavaDoc {
496         // TODO Auto-generated method stub
497
return null;
498     }
499
500     /* (non-Javadoc)
501      * @see org.aopalliance.intercept.ConstructorInterceptor#construct(org.aopalliance.intercept.ConstructorInvocation)
502      */

503     public Object JavaDoc construct(ConstructorInvocation invocation)
504         throws Throwable JavaDoc {
505         // TODO Auto-generated method stub
506
return null;
507     }
508
509 }
510
Popular Tags