View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership. The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License. You may obtain a copy of the License at
9    * 
10   *      http://www.apache.org/licenses/LICENSE-2.0
11   * 
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.river.fiddler.proxy;
19  
20  import java.io.IOException;
21  import java.io.InvalidObjectException;
22  import java.io.ObjectInputStream;
23  import java.lang.reflect.Method;
24  import java.rmi.RemoteException;
25  import net.jini.core.constraint.MethodConstraints;
26  import net.jini.core.constraint.RemoteMethodControl;
27  import net.jini.core.lease.Lease;
28  import net.jini.core.lease.LeaseMap;
29  import net.jini.core.lease.UnknownLeaseException;
30  import net.jini.id.ReferentUuid;
31  import net.jini.id.ReferentUuids;
32  import net.jini.id.Uuid;
33  import net.jini.security.proxytrust.ProxyTrustIterator;
34  import net.jini.security.proxytrust.SingletonProxyTrustIterator;
35  import org.apache.river.api.io.AtomicSerial;
36  import org.apache.river.api.io.AtomicSerial.GetArg;
37  import org.apache.river.lease.AbstractLease;
38  import org.apache.river.lease.ID;
39  import org.apache.river.proxy.ConstrainableProxyUtil;
40  
41  /**
42   * When the Fiddler implementation of the lookup discovery service grants
43   * a lease on a registration requested by a client, a proxy to that lease
44   * is provided to allow the client to interact with the granted lease.
45   * This class is the implementation of that proxy.
46   * <p>
47   * Clients only see instances of this class via the <code>Lease</code>
48   * interface.
49   *
50   * @author Sun Microsystems, Inc.
51   *
52   */
53  @AtomicSerial
54  public class FiddlerLease extends AbstractLease 
55                     implements ReferentUuid, ID<Uuid>
56  {
57  
58      private static final long serialVersionUID = 2L;
59  
60      /**
61       * The reference to the back-end server of the lookup discovery service
62       * that granted this lease (the granting entity).
63       *
64       * @serial
65       */
66      final Fiddler server;
67      /**
68       * The unique ID associated with the server referenced in this class
69       * (used to compare server references).
70       *
71       * @serial
72       */
73      final Uuid serverID;
74      /**
75       * The unique identifier assigned by the lookup discovery service to
76       * the registration to which this lease corresponds.
77       *
78       * @serial
79       */
80      final Uuid registrationID;
81      /**
82       * The internal identifier assigned to this lease by the granting entity.
83       *
84       * @serial
85       */
86      final Uuid leaseID;
87  
88      /**
89       * Public static factory method that creates and returns an instance of 
90       * <code>FiddlerLease</code>. If the server associated with this proxy
91       * implements <code>RemoteMethodControl</code>, then the object returned by
92       * this method will also implement <code>RemoteMethodControl</code>.
93       * 
94       * @param server         reference to the server object through which 
95       *                       communication occurs between the client-side and
96       *                       server-side of the associated service.
97       * @param serverID       the service ID of the service referenced by the
98       *                       server parameter 
99       * @param registrationID the unique identifier assigned by the service to
100      *                       each instance of this proxy
101      * @param leaseID        identifier assigned to this lease by the
102      *                       granting entity
103      * @param expiration     the time of expiration of the lease being granted
104      * 
105      * @return an instance of <code>FiddlerLease</code> that implements
106      *         <code>RemoteMethodControl</code> if the given
107      *         <code>server</code> does.
108      */
109     public static FiddlerLease createLease(Fiddler server,
110                                            Uuid serverID,
111                                            Uuid registrationID,
112                                            Uuid leaseID,
113                                            long expiration)
114     {
115         if(server instanceof RemoteMethodControl) {
116             return new ConstrainableFiddlerLease(server,
117                                                  serverID,
118                                                  registrationID,
119                                                  leaseID,
120                                                  expiration,
121                                                  null);//method constraints
122         } else {
123             return new FiddlerLease(server,
124                                     serverID,
125                                     registrationID,
126                                     leaseID,
127                                     expiration);
128         }//endif
129     }//end createLease
130 
131     /**
132      * Constructs a proxy to the lease the Fiddler implementation of the
133      * lookup discovery service places on a client's requested registration.
134      * The lease corresponding to the constructed proxy will have as its
135      * expiration time, the time input to the <code>expiration</code>
136      * parameter.
137      *
138      * @param server         reference to the back-end server of the lookup
139      *                       discovery service that granted this lease (the
140      *                       granting entity)
141      * @param serverID       the service ID of the service referenced by the
142      *                       server parameter 
143      * @param registrationID unique identifier assigned to the registration
144      *                       to which this lease corresponds
145      * @param leaseID        identifier assigned to this lease by the
146      *                       granting entity
147      * @param expiration     the time of expiration of the lease being granted
148      */
149     private FiddlerLease(Fiddler server,
150                          Uuid serverID,
151                          Uuid registrationID,
152                          Uuid leaseID,
153                          long expiration)
154     {
155         super(expiration);
156         this.server         = server;
157         this.serverID       = serverID;
158         this.registrationID = registrationID;
159         this.leaseID        = leaseID;
160     }//end constructor
161 
162     FiddlerLease(GetArg arg) throws IOException {
163 	super(check(arg));
164 	this.server = (Fiddler) arg.get("server", null);
165 	this.serverID = (Uuid) arg.get("serverID", null);
166 	this.registrationID = (Uuid) arg.get("registrationID", null);
167 	this.leaseID = (Uuid) arg.get("leaseID", null);
168     }
169     
170     private static GetArg check(GetArg arg) throws IOException {
171 	check((Fiddler) arg.get("server", null),
172 		(Uuid) arg.get("serverID", null),
173 		(Uuid) arg.get("registrationID", null));
174 	Object leaseID = arg.get("leaseID", null);
175 	if (leaseID == null || leaseID instanceof Uuid){
176 		return arg;
177 	} else {
178 	    throw new InvalidObjectException("leaseID not instanceof Uuid");
179 	}
180     }
181 
182     /**
183      * Creates a <code>LeaseMap</code> object that can contain leases whose
184      * renewal or cancellation can be batched. Additionally, upon creating
185      * the map the current lease is placed in the map as a key, and
186      * the value of the <code>duration</code> parameter is placed in
187      * the map as the lease's corresponding mapped value of type
188      * <code>Long</code>.
189      *
190      * @param duration the amount of time (in milliseconds) during which
191      *                 the lease being placed in the map will remain in
192      *                 effect. This value will be converted to an instance
193      *                 of <code>Long</code> prior to being placed in the
194      *                 map with its associated lease.
195      *                 the lease in the map.
196      *                      
197      * @return an instance of <code>LeaseMap</code> that contains as its
198      *         first mapping, the ordered pair consisting of this lease
199      *         and the value of the <code>duration</code> parameter.
200      *
201      * @see net.jini.core.lease.Lease#createLeaseMap
202      */
203     public LeaseMap<FiddlerLease,Long> createLeaseMap(long duration) {
204         return FiddlerLeaseMap.createLeaseMap(this, duration);
205     }
206 
207     /**
208      * Examines the input parameter to determine if that parameter, along
209      * with the current lease (the current instance of this class), can
210      * be batched in a <code>LeaseMap</code>.
211      * <p>
212      * For this implementation of the service, two leases can be batched
213      * (placed in the same service-specific instance of <code>LeaseMap</code>)
214      * if those leases satisfy the following conditions:
215      * </p><ul>
216      *    <li> the leases are the same type; that is, the leases are both
217      *         instances of the same, service-specific <code>Lease</code>
218      *         implementation
219      *    <li> the leases were granted by the same backend server
220      *    </ul>     
221      * @param lease reference to the <code>Lease</code> object that this
222      *              method examines for batching compatibility with the
223      *              the current current instance of this class
224      *                      
225      * @return <code>true</code> if the input parameter is compatible for
226      *         batching with the current current instance of this class,
227      *         <code>false</code> otherwise
228      *
229      * @see net.jini.core.lease.Lease#canBatch
230      */
231     public boolean canBatch(Lease lease) {
232         return (    (lease instanceof FiddlerLease)
233                  && (serverID.equals(((FiddlerLease)lease).serverID))  );
234     }//end FiddlerLease.canBatch
235 
236     /**
237      * Returns a reference to the back-end server of the lookup discovery
238      * service that granted this lease.
239      *                      
240      * @return an instance of the Fiddler implementation of the lookup
241      *         discovery service.
242      */
243     Fiddler getServer() {
244         return server;
245     }
246 
247     /**
248      * Returns the unique ID associated with the server referenced in this
249      * class.
250      *                      
251      * @return an instance of the <code>Uuid</code> that contains the
252      *         universally unique ID associated with the server referenced
253      *         in this class.
254      */
255     Uuid getServerID() {
256         return serverID;
257     }
258 
259     /**
260      * Returns the unique identifier assigned by the lookup discovery 
261      * service to the registration to which the current lease corresponds.
262      *                      
263      * @return a <code>net.jini.id.Uuid</code> value
264      *         corresponding to the unique ID assigned to the registration
265      *         associated with the current lease.
266      */
267     Uuid getRegistrationID() {
268         return registrationID;
269     }
270 
271     /**
272      * Returns the identifier assigned to the current lease by the entity
273      * that granted it.
274      *                      
275      * @return a <code>long</code> value corresponding to the ID assigned
276      *         to the current lease.
277      */
278     Uuid getLeaseID() {
279         return leaseID;
280     }
281 
282     /**
283      * This method allows the entity to which the current lease is granted
284      * (the lease holder) to indicate that it is no longer interested
285      * in the resources provided to the entity by the lookup discovery
286      * service. When an entity invokes this method, the overall effect 
287      * is the same as if the lease expired, except that expiration occurs
288      * immediately instead of at the end of a pre-agreed duration.
289      *
290      * @throws net.jini.core.lease.UnknownLeaseException this exception occurs
291      *         when the lease being cancelled is unknown to the lease grantor.
292      * 
293      * @throws java.rmi.RemoteException typically, this exception occurs when
294      *         there is a communication failure between the client and the
295      *         server. When this exception does occur, the lease may or may
296      *         not have been cancelled successfully.
297      *
298      * @see net.jini.core.lease.Lease#cancel
299      */
300     public void cancel() throws UnknownLeaseException, RemoteException {
301         server.cancelLease(registrationID, leaseID);
302     }
303 
304     /** 
305      * This method allows the entity to which the current lease is granted
306      * (the lease holder) to indicate that it is still interested in the
307      * resources of the lookup discovery service, and to request continued
308      * access to those resources for an amount of time (in milliseconds)
309      * relative to the current time. That is, the duration is not added
310      * added to the current expiration, but is added to the current time.
311      * <p>
312      * Note that the duration of the renewed lease will be no greater than
313      * the requested duration, and may be less than that duration.
314      *
315      * @param duration the requested duration for the lease being renewed
316      *
317      * @return <code>long</code> value representing the actual duration that
318      *         was granted for the renewed lease. Note that the actual
319      *         duration granted and returned by this method may be less than
320      *         the duration requested.
321      *
322      * @throws net.jini.core.lease.UnknownLeaseException this exception occurs
323      *         when the lease being renewed does not exist, or is unknown
324      *         to the lease grantor; typically because the lease has expired.
325      *         
326      * @throws java.rmi.RemoteException typically, this exception occurs when
327      *         there is a communication failure between the client and the
328      *         server. When this exception does occur, the lease may or may
329      *         not have been renewed successfully.
330      *
331      * @see net.jini.core.lease.Lease#renew
332      * @see org.apache.river.lease.AbstractLease#renew
333      * @see org.apache.river.lease.AbstractLease#doRenew
334      */
335     protected long doRenew(long duration)
336                                  throws UnknownLeaseException, RemoteException
337     {
338         return server.renewLease(registrationID, leaseID, duration);
339     }
340 
341     /** 
342      * Returns the universally unique identifier that has been assigned to the
343      * resource this proxy represents.
344      *
345      * @return the instance of <code>Uuid</code> that is associated with the
346      *         resource this proxy represents. This method will not return
347      *         <code>null</code>.
348      *
349      * @see net.jini.id.ReferentUuid
350      */
351     public Uuid getReferentUuid() {
352         return leaseID;
353     }
354 
355     /** 
356      * For any instance of this class, returns the hashcode value generated
357      * by the hashCode method of the lease ID associated with the current
358      * instance of this lease.
359      *
360      * @return <code>int</code> value representing the hashcode for an
361      *         instance of this class.
362      */
363     public int hashCode() {
364         return leaseID.hashCode();
365     }
366 
367     /** 
368      * For any instance of this class, indicates whether the object input
369      * to this method is equal to the current instance of this class; where
370      * equality of leases granted by a lookup discovery service is defined by
371      * reference equality. That is, two leases are equal if they reference
372      * (are proxies to) the same backend lease server.
373      *
374      * @param obj reference to the object that is to be compared to the
375      *            object on which this method is invoked.
376      *
377      * @return <code>true</code> if the object input is referentially
378      *         equal to the object on which this method is invoked;
379      *         <code>false</code> otherwise.
380      */
381     public boolean equals(Object obj) {
382         return ReferentUuids.compare(this,obj);
383     }
384 
385     /** When an instance of this class is deserialized, this method is
386      *  automatically invoked. This implementation of this method validates
387      *  the state of the deserialized instance.
388      *
389      * @throws InvalidObjectException if the state of the
390      *         deserialized instance of this class is found to be invalid.
391      */
392     private void readObject(ObjectInputStream s)  
393                                throws IOException, ClassNotFoundException
394     {
395         s.defaultReadObject();
396 	check(server, serverID, registrationID);
397     }//end readObject
398     
399     private static boolean check(Fiddler server, Uuid serverID, Uuid registrationID)
400 	throws InvalidObjectException
401 {
402         /* Verify server */
403         if(server == null) {
404             throw new InvalidObjectException("FiddlerLease.readObject "
405                                              +"failure - server "
406                                              +"field is null");
407         }//endif
408         /* Verify serverID */
409         if(serverID == null) {
410             throw new InvalidObjectException("FiddlerLease.readObject "
411                                              +"failure - serverID "
412                                              +"field is null");
413         }//endif
414         /* Verify registrationID */
415         if(registrationID == null) {
416             throw new InvalidObjectException("FiddlerLease.readObject "
417                                              +"failure - registrationID "
418                                              +"field is null");
419         }//endif
420 	return true;
421     }
422 
423     /** During deserialization of an instance of this class, if it is found
424      *  that the stream contains no data, this method is automatically
425      *  invoked. Because it is expected that the stream should always 
426      *  contain data, this implementation of this method simply declares
427      *  that something must be wrong.
428      *
429      * @throws InvalidObjectException to indicate that there
430      *         was no data in the stream during deserialization of an
431      *         instance of this class; declaring that something is wrong.
432      */
433     private void readObjectNoData() throws InvalidObjectException {
434         throw new InvalidObjectException("no data found when attempting to "
435                                          +"deserialize FiddlerLease instance");
436     }//end readObjectNoData
437 
438     public Uuid identity() {
439         return leaseID;
440     }
441 
442     void setExpiration(long expiration) {
443         this.expiration = expiration;
444     }
445 
446     /** The constrainable version of the class <code>FiddlerLease</code>. 
447      *  <p>
448      *  When a client obtains an instance of this proxy class, the client
449      *  should not attempt to use the proxy until the client is assured
450      *  that the proxy can be trusted. In addition to implementing the
451      *  methods and mechanisms required by <code>RemoteMethodControl</code>, 
452      *  this class - in conjunction with the service's
453      *  <code>ProxyVerifier</code> class, helps provide a mechanism
454      *  for verifying trust in the proxy on behalf of a client.
455      *  <p>
456      *  In order to verify that an instance of this class is trusted, 
457      *  trust must be verified in all subsidiary objects (contained in that
458      *  instance) through which the client ultimately makes calls (local or
459      *  remote).  With respect to this class, the <code>server</code> field
460      *  is a proxy object through which the client makes remote calls to the 
461      *  service's backend. Therefore, trust in that object must be
462      *  verified. Additionally, this class also contains a field of type
463      *  <code>Uuid</code> (<code>registrationID</code> which should be
464      *  tested for trust. Consider the following diagram:
465      *  <p>
466      *  <pre>
467      *    FiddlerLease {
468      *        Fiddler server
469      *        Uuid registrationID
470      *    }//end FiddlerLease
471      *  </pre>
472      *  <p>
473      *  Thus, in order to verify that an instance of this class is trusted,
474      *  trust must be verified in the following objects from the diagram
475      *  above:
476      *  <ul><li> server
477      *      <li> registrationID
478      *  </ul>
479      *
480      *  When a client obtains an instance of this proxy class, the
481      *  deserialization process which delivers the proxy to the client
482      *  invokes the <code>readObject</code> method of this class. Part of
483      *  trust verification is performed in the <code>readObject</code> method,
484      *  and part is performed when the client prepares the proxy. Thus, this
485      *  class' participation in the trust verification process can be
486      *  summarized as follows:
487      *  <p>
488      *  <ul>
489      *    <li> server
490      *      <ul>
491      *        <li> readObject
492      *          <ul>
493      *            <li> verify server != null
494      *            <li> verify server implements RemoteMethodControl
495      *            <li> verify server's method constraints are the same
496      *                 as those placed on the corresponding public Remote
497      *                 methods of its outer proxy class
498      *          </ul>
499      *        <li> proxy preparation
500      *          <ul>
501      *            <li> Security.verifyObjectTrust() which calls
502      *            <li> ProxyVerifier.isTrustedObject() which calls
503      *            <li> canonicalServerObject.checkTrustEquivalence(server)
504      *                 (whose implementation is supplied by the particular 
505      *                 RMI implementation that was used to export the server)
506      *          </ul>
507      *      </ul>
508      *    <li> registrationID
509      *      <ul><li> readObject
510      *          <ul><li> verify registrationID != null</ul>
511      *      </ul>
512      *  </ul>
513      *
514      * @since 2.0
515      */
516     @AtomicSerial
517     static final class ConstrainableFiddlerLease extends FiddlerLease
518                                                  implements RemoteMethodControl, ID<Uuid>
519     {
520         static final long serialVersionUID = 2L;
521 
522         /* Convenience fields containing, respectively, the renew and cancel
523          * methods defined in the Lease interface. These fields are used in
524          * the method mapping array, and when retrieving method constraints
525          * for comparison in canBatch().
526          */
527         private static final Method renewMethod =
528                              ProxyUtil.getMethod(Lease.class,
529                                                  "renew",
530                                                  new Class[] {long.class} );
531         private static final Method cancelMethod =
532                              ProxyUtil.getMethod(Lease.class,
533                                                  "cancel",
534                                                  new Class[] {} );
535 
536         /** Array containing element pairs in which each pair of elements
537          *  represents a correspondence 'mapping' between two methods having
538          *  the following characteristics:
539          *  - the first element in the pair is one of the public, remote
540          *    method(s) that may be invoked by the client through the proxy
541          *    class that this class extends
542          *  - the second element in the pair is the method, implemented
543          *    in the backend server class, that is ultimately executed in
544          *    the server's backend when the client invokes the corresponding
545          *    method in this proxy
546          */
547         private static final Method[] methodMapArray = 
548         {
549             renewMethod, ProxyUtil.getMethod(Fiddler.class,
550                                              "renewLease", 
551                                              new Class[] {Uuid.class,
552                                                           Uuid.class,
553                                                           long.class} ),
554 
555             cancelMethod, ProxyUtil.getMethod(Fiddler.class,
556                                               "cancelLease", 
557                                               new Class[] {Uuid.class,
558                                                            Uuid.class} )
559         };//end methodMapArray
560 
561         /** In order to determine if this lease can be batched with another
562          *  given lease, the method <code>canBatch</code> must verify that
563          *  the corresponding methods of each lease have equivalent
564          *  constraints. The array defined here contains the set of methods
565          *  whose constraints will be compared in <code>canBatch</code>.
566          */
567         private static final Method[] canBatchMethodMapArray =
568                                             { renewMethod,  renewMethod,
569                                               cancelMethod, cancelMethod
570                                             };//end canBatchMethodMapArray
571 
572         /** Client constraints placed on this proxy (may be <code>null</code>).
573          *
574          * @serial
575          */
576         private MethodConstraints methodConstraints;
577 
578         /** Constructs a new <code>ConstrainableFiddlerLease</code> instance.
579          *  <p>
580          *  For a description of all but the <code>methodConstraints</code>
581          *  argument (provided below), refer to the description for the
582          *  constructor of this class' super class.
583          *
584          *  @param methodConstraints the client method constraints to place on
585          *                           this proxy (may be <code>null</code>).
586          */
587         private ConstrainableFiddlerLease(Fiddler server, 
588                                           Uuid serverID,
589                                           Uuid registrationID,
590                                           Uuid leaseID,
591                                           long expiration,
592                                           MethodConstraints methodConstraints)
593         {
594             super( constrainServer(server, methodConstraints),
595                    serverID, registrationID, leaseID, expiration );
596 	    this.methodConstraints = methodConstraints;
597         }//end constructor
598 
599         /**
600 	 * {@link AtomicSerial} constructor.
601 	 * @param arg
602 	 * @throws IOException 
603 	 */
604 	ConstrainableFiddlerLease(GetArg arg) throws IOException {
605 	    super(check(arg));
606 	    this.methodConstraints 
607 		    = (MethodConstraints) arg.get("methodConstraints", null);
608 	}
609 	
610 	private static GetArg check(GetArg arg) throws IOException{
611 	    FiddlerLease fl = new FiddlerLease(arg);
612 	    MethodConstraints methodConstraints 
613 		    = (MethodConstraints) arg.get("methodConstraints", null);
614 	    ConstrainableProxyUtil.verifyConsistentConstraints
615                                                        (methodConstraints,
616                                                         fl.server,
617                                                         methodMapArray);
618 	    return arg;
619 	}
620 
621         /**
622          * Examines the input parameter to determine if that parameter, along
623          * with the current lease (the current instance of this class), can
624          * be batched in a <code>LeaseMap</code>.
625          * <p>
626          * For this implementation of the service, two leases can be
627          * batched (placed in the same service-specific instance of
628          * <code>LeaseMap</code>) if those leases satisfy the following
629          * conditions:
630          * <p><ul>
631          *    <li> the leases are the same type; that is, the leases are 
632          *         both instances of the same, constrainable, service-specific
633          *         <code>Lease</code> implementation
634          *    <li> the leases were granted by the same backend server
635          *    <li> the leases have the same constraints
636          *                      
637          * @param lease reference to the <code>Lease</code> object that this
638          *              method examines for batching compatibility with the
639          *              the current instance of this class
640          *                      
641          * @return <code>true</code> if the input parameter is compatible for
642          *         batching with the current instance of this class,
643          *         <code>false</code> otherwise
644          *
645          * @see net.jini.core.lease.Lease#canBatch
646          */
647         public boolean canBatch(Lease lease) {
648             if( !(super.canBatch(lease)) )  return false;
649             /* Non-constrainable batch criteria satisfied, now handle 
650              * constrainable case.
651              */
652             if( !(lease instanceof ConstrainableFiddlerLease) ) return false;
653             /* Compare constraints */
654             return ConstrainableProxyUtil.equivalentConstraints
655                         ( methodConstraints,
656                           ((ConstrainableFiddlerLease)lease).methodConstraints,
657                           canBatchMethodMapArray );
658         }//end ConstrainableFiddlerLease.canBatch
659 
660         /** Returns a copy of the given server proxy having the client method
661          *  constraints that result after the specified method mapping is
662          *  applied to the given client method constraints.
663          */
664         private static Fiddler constrainServer( Fiddler server,
665                                                 MethodConstraints constraints )
666         {
667             MethodConstraints newConstraints 
668                = ConstrainableProxyUtil.translateConstraints(constraints,
669                                                              methodMapArray);
670             RemoteMethodControl constrainedServer = 
671                 ((RemoteMethodControl)server).setConstraints(newConstraints);
672 
673             return ((Fiddler)constrainedServer);
674         }//end constrainServer
675 
676         /** Returns a new copy of this proxy class 
677          *  (<code>ConstrainableFiddlerLease</code>) with its client
678          *  constraints set to the specified constraints. A <code>null</code>
679          *  value is interpreted as mapping all methods to empty constraints.
680          */
681         public RemoteMethodControl setConstraints
682                                               (MethodConstraints constraints)
683         {
684             return (new ConstrainableFiddlerLease(server,
685                                                   serverID,
686                                                   registrationID,
687                                                   leaseID,
688                                                   expiration,
689                                                   constraints));
690         }//end setConstraints
691 
692         /** Returns the client constraints placed on the current instance
693          *  of this proxy class (<code>ConstrainableFiddlerLease</code>).
694          *  The value returned by this method can be <code>null</code>,
695          *  which is interpreted as mapping all methods to empty constraints.
696          */
697         public MethodConstraints getConstraints() {
698             return methodConstraints;
699         }//end getConstraints
700 
701         /** Returns a proxy trust iterator that is used in 
702          *  <code>ProxyTrustVerifier</code> to retrieve this object's
703          *  trust verifier.
704          */
705         private ProxyTrustIterator getProxyTrustIterator() {
706 	    return new SingletonProxyTrustIterator(server);
707         }//end getProxyTrustIterator
708 
709         /** Performs various functions related to the trust verification
710          *  process for the current instance of this proxy class, as
711          *  detailed in the description for this class.
712          *
713          * @throws <code>InvalidObjectException</code> if any of the
714          *         requirements for trust verification (as detailed in the 
715          *         class description) are not satisfied.
716          */
717         private void readObject(ObjectInputStream s)  
718                                    throws IOException, ClassNotFoundException
719         {
720             /* Note that basic validation of the fields of this class was
721              * already performed in the readObject() method of this class'
722              * super class.
723              */
724             s.defaultReadObject();
725             /* Verify the server and its constraints */
726             ConstrainableProxyUtil.verifyConsistentConstraints
727                                                        (methodConstraints,
728                                                         server,
729                                                         methodMapArray);
730         }//end readObject
731 
732         public void setExpiration(long expiration) {
733             synchronized (this) {
734                 this.expiration = expiration;
735             }
736         }
737 
738     }//end class ConstrainableFiddlerLease
739 
740 }//end class FiddlerLease