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 org.apache.river.admin.DestroyAdmin; 21 import org.apache.river.proxy.ConstrainableProxyUtil; 22 import org.apache.river.admin.FiddlerAdmin; 23 import java.io.IOException; 24 import java.io.InvalidObjectException; 25 import java.io.ObjectInputStream; 26 import java.io.Serializable; 27 import java.lang.reflect.Method; 28 import java.rmi.RemoteException; 29 import net.jini.admin.JoinAdmin; 30 import net.jini.core.constraint.MethodConstraints; 31 import net.jini.core.constraint.RemoteMethodControl; 32 import net.jini.core.discovery.LookupLocator; 33 import net.jini.core.entry.Entry; 34 import net.jini.id.ReferentUuid; 35 import net.jini.id.ReferentUuids; 36 import net.jini.id.Uuid; 37 import net.jini.security.proxytrust.ProxyTrustIterator; 38 import net.jini.security.proxytrust.SingletonProxyTrustIterator; 39 import org.apache.river.api.io.AtomicSerial; 40 import org.apache.river.api.io.AtomicSerial.GetArg; 41 42 /** 43 * This class is a proxy providing access to the methods of an implementation 44 * of the lookup discovery service which allow the administration of the 45 * service. Clients only see instances of this class via the FiddlerAdmin 46 * interface. 47 * 48 * @author Sun Microsystems, Inc. 49 * 50 */ 51 @AtomicSerial 52 public class FiddlerAdminProxy implements FiddlerAdmin, ReferentUuid, Serializable { 53 54 private static final long serialVersionUID = 2L; 55 56 /** 57 * The reference through which communication occurs between the 58 * client-side and the server-side of the lookup discovery service 59 * 60 * @serial 61 */ 62 final Fiddler server; 63 /** 64 * The unique identifier assigned to the current instance of this 65 * proxy class by the lookup discovery service. This ID is used to 66 * determine equality between proxies. 67 * 68 * @serial 69 */ 70 final Uuid proxyID; 71 72 /** 73 * Public static factory method that creates and returns an instance of 74 * <code>FiddlerAdminProxy</code>. If the server associated with this proxy 75 * implements <code>RemoteMethodControl</code>, then the object returned by 76 * this method will also implement <code>RemoteMethodControl</code>. 77 * 78 * @param server reference to the server object through which 79 * communication occurs between the client-side and 80 * server-side of the associated service. 81 * @param proxyID the unique identifier assigned by the service to each 82 * instance of this proxy 83 * 84 * @return an instance of <code>FiddlerAdminProxy</code> that implements 85 * <code>RemoteMethodControl</code> if the given <code>server</code> 86 * does. 87 */ 88 public static FiddlerAdminProxy createAdminProxy(Fiddler server, 89 Uuid proxyID) 90 { 91 if(server instanceof RemoteMethodControl) { 92 return new ConstrainableFiddlerAdminProxy(server, proxyID, null); 93 } else { 94 return new FiddlerAdminProxy(server, proxyID); 95 }//endif 96 }//end createAdminProxy 97 98 /** 99 * Constructs a new instance of FiddlerAdminProxy. 100 * 101 * @param server reference to the server object through which 102 * communication occurs between the client-side and 103 * server-side of the associated service 104 * @param proxyID the unique identifier assigned by the service to each 105 * instance of this proxy 106 */ 107 private FiddlerAdminProxy(Fiddler server, Uuid proxyID) { 108 this.server = server; 109 this.proxyID = proxyID; 110 }//end constructor 111 112 /** 113 * {@link AtomicSerial} constructor. 114 * @param arg 115 * @throws IOException 116 */ 117 FiddlerAdminProxy(GetArg arg) throws IOException { 118 this((Fiddler)arg.get("server", null), (Uuid) arg.get("proxyID", null)); 119 } 120 121 /* *** Methods of org.apache.river.fiddler.FiddlerAdmin *** */ 122 123 /** 124 * Changes the least upper bound applied to all lease durations granted 125 * by the lookup discovery service. 126 * <p> 127 * This method is a mechanism for an entity with the appropriate 128 * privileges to administratively change the value of the least upper 129 * bound that will be applied by the Fiddler implementation of the lookup 130 * discovery service when determining the duration to assign to the lease 131 * on a requested registration. 132 * 133 * @param newBound <code>long</code> value representing the new least 134 * upper bound (in milliseconds) on the set of all possible 135 * lease durations that may be granted 136 * 137 * @throws java.rmi.RemoteException typically, this exception occurs when 138 * there is a communication failure between the client and the 139 * lookup discovery service. When this exception does occur, the 140 * bound value may or may not have been changed successfully. 141 * 142 * @see FiddlerAdmin#setLeaseBound 143 */ 144 public void setLeaseBound(long newBound) throws RemoteException { 145 server.setLeaseBound(newBound); 146 } 147 /** 148 * Retrieves the least upper bound applied to all lease durations granted 149 * by the lookup discovery service. 150 * 151 * @return <code>long</code> value representing the current least 152 * upper bound (in milliseconds) on the set of all possible 153 * lease durations that may be granted 154 * 155 * @throws java.rmi.RemoteException typically, this exception occurs when 156 * there is a communication failure between the client and the 157 * lookup discovery service. 158 * 159 * @see FiddlerAdmin#setLeaseBound 160 */ 161 public long getLeaseBound() throws RemoteException { 162 return server.getLeaseBound(); 163 } 164 165 /** 166 * Change the weight factor applied by the lookup discovery service 167 * to the snapshot size during the test to determine whether or not 168 * to take a "snapshot" of the system state. 169 * 170 * @param weight weight factor for snapshot size 171 * 172 * @throws java.rmi.RemoteException typically, this exception occurs when 173 * there is a communication failure between the client and the 174 * lookup discovery service. When this exception does occur, the 175 * weight factor may or may not have been changed successfully. 176 * 177 * @see FiddlerAdmin#setPersistenceSnapshotWeight 178 */ 179 public void setPersistenceSnapshotWeight(float weight) 180 throws RemoteException 181 { 182 server.setPersistenceSnapshotWeight(weight); 183 } 184 185 /** 186 * Retrieve the weight factor applied by the lookup discovery service 187 * to the snapshot size during the test to determine whether or not to 188 * take a "snapshot" of the system state. 189 * 190 * @return float value corresponding to the weight factor for snapshot 191 * size 192 * 193 * @throws java.rmi.RemoteException typically, this exception occurs when 194 * there is a communication failure between the client and the 195 * lookup discovery service. 196 * 197 * @see FiddlerAdmin#getPersistenceSnapshotWeight 198 */ 199 public float getPersistenceSnapshotWeight() throws RemoteException { 200 return server.getPersistenceSnapshotWeight(); 201 } 202 203 /** 204 * Change the value of the size threshold of the snapshot; which is 205 * employed by the lookup discovery service in the test to determine 206 * whether or not to take a "snapshot" of the system state. 207 * 208 * @param threshold size threshold for taking a snapshot 209 * 210 * @throws java.rmi.RemoteException typically, this exception occurs when 211 * there is a communication failure between the client and the 212 * lookup discovery service. When this exception does occur, the 213 * threshold may or may not have been changed successfully. 214 * 215 * @see FiddlerAdmin#setPersistenceSnapshotThreshold 216 */ 217 public void setPersistenceSnapshotThreshold(int threshold) 218 throws RemoteException 219 { 220 server.setPersistenceSnapshotThreshold(threshold); 221 } 222 223 /** 224 * Retrieve the value of the size threshold of the snapshot; which is 225 * employed by the lookup discovery service in the test to determine 226 * whether or not to take a "snapshot" of the system state. 227 * 228 * @return int value corresponding to the size threshold of the snapshot 229 * 230 * @throws java.rmi.RemoteException typically, this exception occurs when 231 * there is a communication failure between the client and the 232 * lookup discovery service. 233 * 234 * @see FiddlerAdmin#getPersistenceSnapshotThreshold 235 */ 236 public int getPersistenceSnapshotThreshold() throws RemoteException { 237 return server.getPersistenceSnapshotThreshold(); 238 } 239 240 /* *** Methods of net.jini.admin.JoinAdmin *** */ 241 242 /** 243 * Get the current attribute sets for the lookup discovery service. 244 * 245 * @return array of net.jini.core.entry.Entry containing the current 246 * attribute sets for the lookup discovery service 247 * 248 * @throws java.rmi.RemoteException typically, this exception occurs when 249 * there is a communication failure between the client and the 250 * lookup discovery service. 251 * 252 * @see net.jini.admin.JoinAdmin#getLookupAttributes 253 */ 254 public Entry[] getLookupAttributes() throws RemoteException { 255 return server.getLookupAttributes(); 256 } 257 258 /** 259 * Add attribute sets to the current set of attributes associated 260 * with the lookup discovery service. The resulting set will be used 261 * for all future registrations with lookup services. The new attribute 262 * sets are also added to the lookup discovery service's attributes 263 * on each lookup service with which the lookup discovery service 264 * is currently registered. 265 * 266 * @param attrSets array of net.jini.core.entry.Entry containing the 267 * attribute sets to add 268 * 269 * @throws java.rmi.RemoteException typically, this exception occurs when 270 * there is a communication failure between the client and the 271 * lookup discovery service. When this exception does occur, the 272 * attributes may or may not have been added successfully. 273 * 274 * @see net.jini.admin.JoinAdmin#addLookupAttributes 275 */ 276 public void addLookupAttributes(Entry[] attrSets) throws RemoteException { 277 server.addLookupAttributes(attrSets); 278 } 279 280 /** 281 * Modify the current set of attributes associated with the lookup 282 * discovery service. The resulting set will be used for all future 283 * registrations with lookup services. The same modifications are 284 * also made to the lookup discovery service's attributes on each 285 * lookup service with which the lookup discovery service is currently 286 * registered. 287 * 288 * @param attrSetTemplates array of net.jini.core.entry.Entry containing 289 * the templates for matching attribute sets 290 * @param attrSets array of net.jini.core.entry.Entry containing the 291 * modifications to make to matching sets 292 * 293 * @throws java.rmi.RemoteException typically, this exception occurs when 294 * there is a communication failure between the client and the 295 * lookup discovery service. When this exception does occur, the 296 * attributes may or may not have been modified successfully. 297 * 298 * @see net.jini.admin.JoinAdmin#modifyLookupAttributes 299 */ 300 public void modifyLookupAttributes(Entry[] attrSetTemplates, 301 Entry[] attrSets) 302 throws RemoteException 303 { 304 server.modifyLookupAttributes(attrSetTemplates, attrSets); 305 } 306 307 /** 308 * Get the names of the groups whose members are lookup services the 309 * lookup discovery services wishes to register with (join). 310 * 311 * @return String array containing the names of the groups whose members 312 * are lookup services the lookup discovery service wishes to 313 * join. 314 * <p> 315 * If the array returned is empty, the lookup discovery service 316 * is configured to join no groups. If null is returned, the 317 * lookup discovery service is configured to join all groups. 318 * 319 * @throws java.rmi.RemoteException typically, this exception occurs when 320 * there is a communication failure between the client and the 321 * lookup discovery service. 322 * 323 * @see net.jini.admin.JoinAdmin#getLookupGroups 324 */ 325 public String[] getLookupGroups() throws RemoteException { 326 return server.getLookupGroups(); 327 } 328 329 /** 330 * Add new names to the set consisting of the names of groups whose 331 * members are lookup services the lookup discovery service wishes 332 * to register with (join). Any lookup services belonging to the 333 * new groups that the lookup discovery service has not yet registered 334 * with, will be discovered and joined. 335 * 336 * @param groups String array containing the names of the groups to add 337 * 338 * @throws java.rmi.RemoteException typically, this exception occurs when 339 * there is a communication failure between the client and the 340 * lookup discovery service. When this exception does occur, the 341 * group names may or may not have been added successfully. 342 * 343 * @see net.jini.admin.JoinAdmin#addLookupGroups 344 */ 345 public void addLookupGroups(String[] groups) throws RemoteException { 346 server.addLookupGroups(groups); 347 } 348 349 /** 350 * Remove a set of group names from lookup discovery service's managed 351 * set of groups (the set consisting of the names of groups whose 352 * members are lookup services the lookup discovery service wishes 353 * to join). Any leases granted to the lookup discovery service by 354 * lookup services that are not members of the groups whose names 355 * remain in the managed set will be cancelled at those lookup services. 356 * 357 * @param groups String array containing the names of the groups to remove 358 * 359 * @throws java.rmi.RemoteException typically, this exception occurs when 360 * there is a communication failure between the client and the 361 * lookup discovery service. When this exception does occur, the 362 * group names may or may not have been removed successfully. 363 * 364 * @see net.jini.admin.JoinAdmin#removeLookupGroups 365 */ 366 public void removeLookupGroups(String[] groups) throws RemoteException { 367 server.removeLookupGroups(groups); 368 } 369 370 /** 371 * Replace the lookup discovery service's managed set of groups with a 372 * new set of group names. Any leases granted to the lookup discovery 373 * service by lookup services that are not members of the groups whose 374 * names are in the new managed set will be cancelled at those lookup 375 * services. Lookup services that are members of groups reflected in 376 * the new managed set will be discovered and joined. 377 * 378 * @param groups String array containing the names of the new groups 379 * 380 * @throws java.rmi.RemoteException typically, this exception occurs when 381 * there is a communication failure between the client and the 382 * lookup discovery service. When this exception does occur, the 383 * group names may or may not have been replaced successfully. 384 * 385 * @see net.jini.admin.JoinAdmin#setLookupGroups 386 */ 387 public void setLookupGroups(String[] groups) throws RemoteException { 388 server.setLookupGroups(groups); 389 } 390 391 /** 392 * Get the lookup discovery service's managed set of locators. The 393 * managed set of locators is the set of LookupLocator objects 394 * corresponding to the specific lookup services with which the lookup 395 * discovery service wishes to register (join). 396 * 397 * @return array of objects of type net.jini.core.discovery.LookupLocator, 398 * each of which corresponds to a specific lookup service the 399 * lookup discovery service wishes to join. 400 * 401 * @throws java.rmi.RemoteException typically, this exception occurs when 402 * there is a communication failure between the client and the 403 * lookup discovery service. 404 * 405 * @see net.jini.admin.JoinAdmin#getLookupLocators 406 */ 407 public LookupLocator[] getLookupLocators() throws RemoteException { 408 return server.getLookupLocators(); 409 } 410 411 /** 412 * Add a set of LookupLocator objects to the lookup discovery service's 413 * managed set of locators. The managed set of locators is the set of 414 * LookupLocator objects corresponding to the specific lookup services 415 * with which the lookup discovery service wishes to register (join). 416 * <p> 417 * Any lookup services corresponding to the new locators that the lookup 418 * discovery service has not yet joined, will be discovered and joined. 419 * 420 * @param locators array of net.jini.core.discovery.LookupLocator objects to add 421 * to the managed set of locators 422 * 423 * @throws java.rmi.RemoteException typically, this exception occurs when 424 * there is a communication failure between the client and the 425 * lookup discovery service. When this exception does occur, the 426 * new locators may or may not have been added successfully. 427 * 428 * @see net.jini.admin.JoinAdmin#addLookupLocators 429 */ 430 public void addLookupLocators(LookupLocator[] locators) 431 throws RemoteException 432 { 433 server.addLookupLocators(locators); 434 } 435 436 /** 437 * Remove a set of LookupLocator objects from the lookup discovery 438 * service's managed set of locators. The managed set of locators is the 439 * set of LookupLocator objects corresponding to the specific lookup 440 * services with which the lookup discovery service wishes to register 441 * (join). 442 * <p> 443 * Note that any leases granted to the lookup discovery service by 444 * lookup services that do not correspond to any of the locators 445 * remaining in the managed set will be cancelled at those lookup 446 * services. 447 * 448 * @param locators array of net.jini.core.discovery.LookupLocator objects to 449 * remove from the managed set of locators 450 * 451 * @throws java.rmi.RemoteException typically, this exception occurs when 452 * there is a communication failure between the client and the 453 * lookup discovery service. When this exception does occur, the 454 * new locators may or may not have been removed successfully. 455 * 456 * @see net.jini.admin.JoinAdmin#removeLookupLocators 457 */ 458 public void removeLookupLocators(LookupLocator[] locators) 459 throws RemoteException 460 { 461 server.removeLookupLocators(locators); 462 } 463 464 /** 465 * Replace the lookup discovery service's managed set of locators with 466 * a new set of locators. The managed set of locators is the set of 467 * LookupLocator objects corresponding to the specific lookup services 468 * with which the lookup discovery service wishes to register (join). 469 * <p> 470 * Note that any leases granted to the lookup discovery service by 471 * lookup services whose corresponding locator is removed from the 472 * managed set will be cancelled at those lookup services. The lookup 473 * services corresponding to the new locators in the managed set 474 * will be discovered and joined. 475 * 476 * @param locators array of net.jini.core.discovery.LookupLocator objects with 477 * which to replace the current managed set of locators 478 * remove from the managed set of locators 479 * 480 * @throws java.rmi.RemoteException typically, this exception occurs when 481 * there is a communication failure between the client and the 482 * lookup discovery service. When this exception does occur, the 483 * locators in the managed set may or may not have been replaced 484 * successfully. 485 * 486 * @see net.jini.admin.JoinAdmin#setLookupLocators 487 */ 488 public void setLookupLocators(LookupLocator[] locators) 489 throws RemoteException 490 { 491 server.setLookupLocators(locators); 492 } 493 494 /* From net.jini.id.ReferentUuid */ 495 496 /** 497 * Returns the universally unique identifier that has been assigned to the 498 * resource this proxy represents. 499 * 500 * @return the instance of <code>Uuid</code> that is associated with the 501 * resource this proxy represents. This method will not return 502 * <code>null</code>. 503 * 504 * @see net.jini.id.ReferentUuid 505 */ 506 public Uuid getReferentUuid() { 507 return proxyID; 508 } 509 510 /* *** Methods of org.apache.river.admin.DestroyAdmin *** */ 511 512 /** 513 * Destroy the lookup discovery service, if possible, including its 514 * persistent storage. This method will typically spawn a separate 515 * thread to do the actual work asynchronously, so a successful 516 * return from this method usually does not mean that the service 517 * has been destroyed. 518 * 519 * @throws java.rmi.RemoteException typically, this exception occurs when 520 * there is a communication failure between the client and the 521 * lookup discovery service. When this exception does occur, the 522 * lookup discovery service may or may not have been successfully 523 * destroyed. 524 * 525 * @see org.apache.river.admin.DestroyAdmin#destroy 526 */ 527 public void destroy() throws RemoteException { 528 server.destroy(); 529 } 530 531 /* *** HashCode and Equals for this class *** */ 532 533 /** 534 * For any instance of this class, returns the hashcode value generated 535 * by the hashCode method of the proxy ID associated with the current 536 * instance of this proxy. 537 * 538 * @return <code>int</code> value representing the hashcode for an 539 * instance of this class. 540 */ 541 public int hashCode() { 542 return proxyID.hashCode(); 543 } 544 545 /** 546 * For any instance of this class, indicates whether the object input 547 * to this method is equal to the current instance of this class; where 548 * equality of administrative proxies to a lookup discovery service is 549 * defined by reference equality. That is, two proxies are equal if they 550 * reference (are proxies to) the same backend server. 551 * 552 * @param obj reference to the object that is to be compared to the 553 * object on which this method is invoked. 554 * 555 * @return <code>true</code> if the object input is referentially 556 * equal to the object on which this method is invoked; 557 * <code>false</code> otherwise. 558 */ 559 public boolean equals(Object obj) { 560 return ReferentUuids.compare(this,obj); 561 } 562 563 /** When an instance of this class is deserialized, this method is 564 * automatically invoked. This implementation of this method validates 565 * the state of the deserialized instance. 566 * 567 * @throws InvalidObjectException if the state of the 568 * deserialized instance of this class is found to be invalid. 569 */ 570 private void readObject(ObjectInputStream s) 571 throws IOException, ClassNotFoundException 572 { 573 s.defaultReadObject(); 574 /* Verify server */ 575 if(server == null) { 576 throw new InvalidObjectException("FiddlerAdminProxy.readObject " 577 +"failure - server " 578 +"field is null"); 579 }//endif 580 /* Verify proxyID */ 581 if(proxyID == null) { 582 throw new InvalidObjectException("FiddlerAdminProxy.readObject " 583 +"failure - proxyID " 584 +"field is null"); 585 }//endif 586 }//end readObject 587 588 /** During deserialization of an instance of this class, if it is found 589 * that the stream contains no data, this method is automatically 590 * invoked. Because it is expected that the stream should always 591 * contain data, this implementation of this method simply declares 592 * that something must be wrong. 593 * 594 * @throws InvalidObjectException to indicate that there 595 * was no data in the stream during deserialization of an 596 * instance of this class; declaring that something is wrong. 597 */ 598 private void readObjectNoData() throws InvalidObjectException { 599 throw new InvalidObjectException("no data found when attempting to " 600 +"deserialize FiddlerAdminProxy " 601 +"instance"); 602 }//end readObjectNoData 603 604 /** The constrainable version of the class <code>FiddlerAdminProxy</code>. 605 * <p> 606 * When a client obtains an instance of this proxy class, the client 607 * should not attempt to use the proxy until the client is assured 608 * that the proxy can be trusted. In addition to implementing the 609 * methods and mechanisms required by <code>RemoteMethodControl</code>, 610 * this class - in conjunction with the service's 611 * <code>ProxyVerifier</code> class, helps provide a mechanism 612 * for verifying trust in the proxy on behalf of a client. 613 * <p> 614 * In order to verify that an instance of this class is trusted, 615 * trust must be verified in all subsidiary objects (contained in that 616 * instance) through which the client ultimately makes calls (local or 617 * remote). With respect to this class, the <code>server</code> field 618 * is a proxy object through which the client makes remote calls to the 619 * service's backend. Therefore, trust in that object must be 620 * verified. Additionally, this class also contains a field of type 621 * <code>Uuid</code> (<code>proxyID</code> which should be 622 * tested for trust. Consider the following diagram: 623 * <p> 624 * <pre> 625 * FiddlerAdminProxy { 626 * Fiddler server 627 * Uuid proxyID 628 * }//end FiddlerAdminProxy 629 * </pre> 630 * <p> 631 * Thus, in order to verify that an instance of this class is trusted, 632 * trust must be verified in the following objects from the diagram 633 * above: 634 * <ul><li> server 635 * <li> proxyID 636 * </ul> 637 * 638 * When a client obtains an instance of this proxy class, the 639 * deserialization process which delivers the proxy to the client 640 * invokes the <code>readObject</code> method of this class. Part of 641 * trust verification is performed in the <code>readObject</code> method, 642 * and part is performed when the client prepares the proxy. Thus, this 643 * class' participation in the trust verification process can be 644 * summarized as follows: 645 * <p> 646 * <ul> 647 * <li> server 648 * <ul> 649 * <li> readObject 650 * <ul> 651 * <li> verify server != null 652 * <li> verify server implements RemoteMethodControl 653 * <li> verify server's method constraints are the same 654 * as those placed on the corresponding public Remote 655 * methods of its outer proxy class 656 * </ul> 657 * <li> proxy preparation 658 * <ul> 659 * <li> Security.verifyObjectTrust() which calls 660 * <li> ProxyVerifier.isTrustedObject() which calls 661 * <li> canonicalServerObject.checkTrustEquivalence(server) 662 * (whose implementation is supplied by the particular 663 * RMI implementation that was used to export the server) 664 * </ul> 665 * </ul> 666 * <li> proxyID 667 * <ul><li> readObject 668 * <ul><li> verify proxyID != null</ul> 669 * </ul> 670 * </ul> 671 * 672 * @since 2.0 673 */ 674 @AtomicSerial 675 static final class ConstrainableFiddlerAdminProxy 676 extends FiddlerAdminProxy 677 implements RemoteMethodControl 678 { 679 static final long serialVersionUID = 2L; 680 681 /* Array containing element pairs in which each pair of elements 682 * represents a correspondence 'mapping' between two methods having 683 * the following characteristics: 684 * - the first element in the pair is one of the public, remote 685 * method(s) that may be invoked by the client through the proxy 686 * class that this class extends 687 * - the second element in the pair is the method, implemented 688 * in the backend server class, that is ultimately executed in 689 * the server's backend when the client invokes the corresponding 690 * method in this proxy 691 */ 692 private static final Method[] methodMapArray = 693 { 694 ProxyUtil.getMethod(JoinAdmin.class, 695 "getLookupAttributes", new Class[] {} ), 696 ProxyUtil.getMethod(JoinAdmin.class, 697 "getLookupAttributes", new Class[] {} ), 698 699 ProxyUtil.getMethod(JoinAdmin.class, 700 "addLookupAttributes", 701 new Class[] {Entry[].class} ), 702 ProxyUtil.getMethod(JoinAdmin.class, 703 "addLookupAttributes", 704 new Class[] {Entry[].class} ), 705 706 ProxyUtil.getMethod(JoinAdmin.class, 707 "modifyLookupAttributes", 708 new Class[] {Entry[].class, 709 Entry[].class} ), 710 ProxyUtil.getMethod(JoinAdmin.class, 711 "modifyLookupAttributes", 712 new Class[] {Entry[].class, 713 Entry[].class} ), 714 715 ProxyUtil.getMethod(JoinAdmin.class, 716 "getLookupGroups", new Class[] {} ), 717 ProxyUtil.getMethod(JoinAdmin.class, 718 "getLookupGroups", new Class[] {} ), 719 720 ProxyUtil.getMethod(JoinAdmin.class, 721 "addLookupGroups", 722 new Class[] {String[].class} ), 723 ProxyUtil.getMethod(JoinAdmin.class, 724 "addLookupGroups", 725 new Class[] {String[].class} ), 726 727 ProxyUtil.getMethod(JoinAdmin.class, 728 "removeLookupGroups", 729 new Class[] {String[].class} ), 730 ProxyUtil.getMethod(JoinAdmin.class, 731 "removeLookupGroups", 732 new Class[] {String[].class} ), 733 734 ProxyUtil.getMethod(JoinAdmin.class, 735 "setLookupGroups", 736 new Class[] {String[].class} ), 737 ProxyUtil.getMethod(JoinAdmin.class, 738 "setLookupGroups", 739 new Class[] {String[].class} ), 740 741 ProxyUtil.getMethod(JoinAdmin.class, 742 "getLookupLocators", new Class[] {} ), 743 ProxyUtil.getMethod(JoinAdmin.class, 744 "getLookupLocators", new Class[] {} ), 745 746 ProxyUtil.getMethod(JoinAdmin.class, 747 "addLookupLocators", 748 new Class[] {LookupLocator[].class} ), 749 ProxyUtil.getMethod(JoinAdmin.class, 750 "addLookupLocators", 751 new Class[] {LookupLocator[].class} ), 752 753 ProxyUtil.getMethod(JoinAdmin.class, 754 "removeLookupLocators", 755 new Class[] {LookupLocator[].class} ), 756 ProxyUtil.getMethod(JoinAdmin.class, 757 "removeLookupLocators", 758 new Class[] {LookupLocator[].class} ), 759 760 ProxyUtil.getMethod(JoinAdmin.class, 761 "setLookupLocators", 762 new Class[] {LookupLocator[].class} ), 763 ProxyUtil.getMethod(JoinAdmin.class, 764 "setLookupLocators", 765 new Class[] {LookupLocator[].class} ), 766 767 768 ProxyUtil.getMethod(DestroyAdmin.class, 769 "destroy", new Class[] {} ), 770 ProxyUtil.getMethod(DestroyAdmin.class, 771 "destroy", new Class[] {} ), 772 773 ProxyUtil.getMethod(FiddlerAdmin.class, 774 "setLeaseBound", 775 new Class[] {long.class} ), 776 ProxyUtil.getMethod(FiddlerAdmin.class, 777 "setLeaseBound", 778 new Class[] {long.class} ), 779 780 ProxyUtil.getMethod(FiddlerAdmin.class, 781 "getLeaseBound", 782 new Class[] {} ), 783 ProxyUtil.getMethod(FiddlerAdmin.class, 784 "getLeaseBound", 785 new Class[] {} ), 786 787 ProxyUtil.getMethod(FiddlerAdmin.class, 788 "setPersistenceSnapshotWeight", 789 new Class[] {float.class} ), 790 ProxyUtil.getMethod(FiddlerAdmin.class, 791 "setPersistenceSnapshotWeight", 792 new Class[] {float.class} ), 793 794 ProxyUtil.getMethod(FiddlerAdmin.class, 795 "getPersistenceSnapshotWeight", 796 new Class[] {} ), 797 ProxyUtil.getMethod(FiddlerAdmin.class, 798 "getPersistenceSnapshotWeight", 799 new Class[] {} ), 800 801 ProxyUtil.getMethod(FiddlerAdmin.class, 802 "setPersistenceSnapshotThreshold", 803 new Class[] {int.class} ), 804 ProxyUtil.getMethod(FiddlerAdmin.class, 805 "setPersistenceSnapshotThreshold", 806 new Class[] {int.class} ), 807 808 ProxyUtil.getMethod(FiddlerAdmin.class, 809 "getPersistenceSnapshotThreshold", 810 new Class[] {} ), 811 ProxyUtil.getMethod(FiddlerAdmin.class, 812 "getPersistenceSnapshotThreshold", 813 new Class[] {} ) 814 };//end methodMapArray 815 816 /** Client constraints placed on this proxy (may be <code>null</code>). 817 * 818 * @serial 819 */ 820 private MethodConstraints methodConstraints; 821 822 /** Constructs a new <code>ConstrainableFiddlerAdminProxy</code> 823 * instance. 824 * <p> 825 * For a description of all but the <code>methodConstraints</code> 826 * argument (provided below), refer to the description for the 827 * constructor of this class' super class. 828 * 829 * @param methodConstraints the client method constraints to place on 830 * this proxy (may be <code>null</code>). 831 */ 832 private ConstrainableFiddlerAdminProxy 833 (Fiddler server, 834 Uuid proxyID, 835 MethodConstraints methodConstraints) 836 { 837 super( constrainServer(server, methodConstraints), proxyID); 838 this.methodConstraints = methodConstraints; 839 }//end constructor 840 841 private static GetArg check(GetArg arg) throws IOException { 842 FiddlerAdminProxy fap = new FiddlerAdminProxy(arg); 843 MethodConstraints methodConstraints = (MethodConstraints) 844 arg.get("methodConstraints", null); 845 /* Verify the server and its constraints */ 846 ConstrainableProxyUtil.verifyConsistentConstraints 847 (methodConstraints, 848 fap.server, 849 methodMapArray); 850 return arg; 851 } 852 ConstrainableFiddlerAdminProxy(GetArg arg) throws IOException { 853 super(check(arg)); 854 methodConstraints = (MethodConstraints) 855 arg.get("methodConstraints", null); 856 } 857 858 /** Returns a copy of the given server proxy having the client method 859 * constraints that result after the specified method mapping is 860 * applied to the given client method constraints. 861 */ 862 private static Fiddler constrainServer( Fiddler server, 863 MethodConstraints constraints ) 864 { 865 MethodConstraints newConstraints 866 = ConstrainableProxyUtil.translateConstraints(constraints, 867 methodMapArray); 868 RemoteMethodControl constrainedServer = 869 ((RemoteMethodControl)server).setConstraints(newConstraints); 870 871 return ((Fiddler)constrainedServer); 872 }//end constrainServer 873 874 /** Returns a new copy of this proxy class 875 * (<code>ConstrainableFiddlerAdminProxy</code>) with its client 876 * constraints set to the specified constraints. A <code>null</code> 877 * value is interpreted as mapping all methods to empty constraints. 878 */ 879 public RemoteMethodControl setConstraints 880 (MethodConstraints constraints) 881 { 882 return (new ConstrainableFiddlerAdminProxy 883 (server, proxyID, constraints)); 884 }//end setConstraints 885 886 /** Returns the client constraints placed on the current instance 887 * of this proxy class (<code>ConstrainableFiddlerAdminProxy</code>). 888 * The value returned by this method can be <code>null</code>, 889 * which is interpreted as mapping all methods to empty constraints. 890 */ 891 public MethodConstraints getConstraints() { 892 return methodConstraints; 893 }//end getConstraints 894 895 /** Returns a proxy trust iterator that is used in 896 * <code>ProxyTrustVerifier</code> to retrieve this object's 897 * trust verifier. 898 */ 899 private ProxyTrustIterator getProxyTrustIterator() { 900 return new SingletonProxyTrustIterator(server); 901 }//end getProxyTrustIterator 902 903 /** Performs various functions related to the trust verification 904 * process for the current instance of this proxy class, as 905 * detailed in the description for this class. 906 * 907 * @throws <code>InvalidObjectException</code> if any of the 908 * requirements for trust verification (as detailed in the 909 * class description) are not satisfied. 910 */ 911 private void readObject(ObjectInputStream s) 912 throws IOException, ClassNotFoundException 913 { 914 /* Note that basic validation of the fields of this class was 915 * already performed in the readObject() method of this class' 916 * super class. 917 */ 918 s.defaultReadObject(); 919 /* Verify the server and its constraints */ 920 ConstrainableProxyUtil.verifyConsistentConstraints 921 (methodConstraints, 922 server, 923 methodMapArray); 924 }//end readObject 925 926 }//end class ConstrainableFiddlerAdminProxy 927 928 }//end class FiddlerAdminProxy