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.proxy.ConstrainableProxyUtil; 21 import org.apache.river.proxy.ThrowThis; 22 import java.io.IOException; 23 import java.io.InvalidObjectException; 24 import java.io.ObjectInputStream; 25 import java.io.Serializable; 26 import java.lang.reflect.Method; 27 import java.rmi.MarshalledObject; 28 import java.rmi.RemoteException; 29 import java.util.ArrayList; 30 import java.util.HashSet; 31 import net.jini.core.constraint.MethodConstraints; 32 import net.jini.core.constraint.RemoteMethodControl; 33 import net.jini.core.discovery.LookupLocator; 34 import net.jini.core.event.EventRegistration; 35 import net.jini.core.lease.Lease; 36 import net.jini.core.lookup.ServiceRegistrar; 37 import net.jini.discovery.LookupDiscoveryRegistration; 38 import net.jini.discovery.LookupUnmarshalException; 39 import net.jini.id.ReferentUuid; 40 import net.jini.id.ReferentUuids; 41 import net.jini.id.Uuid; 42 import net.jini.io.MarshalledInstance; 43 import net.jini.security.proxytrust.ProxyTrustIterator; 44 import net.jini.security.proxytrust.SingletonProxyTrustIterator; 45 import org.apache.river.api.io.AtomicSerial; 46 import org.apache.river.api.io.AtomicSerial.GetArg; 47 48 /** 49 * This class is an implementation of the LookupDiscoveryRegistration 50 * interface. 51 * <p> 52 * When a client requests a registration with a lookup discovery service, 53 * an instance of this class is returned. This class is used by the client 54 * as a proxy to the registration object created by the lookup discovery 55 * service for the client. The remote methods of this class each have a 56 * counterpart on the back-end server of the Fiddler implementation of the 57 * lookup discovery service. The client can use the methods implemented in 58 * this class to manage the parameters of its registration with the lookup 59 * discovery service. 60 * 61 * @author Sun Microsystems, Inc. 62 * 63 * @see net.jini.discovery.LookupDiscoveryRegistration 64 */ 65 @AtomicSerial 66 public class FiddlerRegistration implements LookupDiscoveryRegistration, 67 ReferentUuid, Serializable 68 { 69 70 private static final long serialVersionUID = 2L; 71 72 /** 73 * The reference through which communication occurs between the 74 * client-side and the server-side of the lookup discovery service 75 * 76 * @serial 77 */ 78 final Fiddler server; 79 /** 80 * The unique identifier assigned to the current instance of this 81 * registration proxy class by the lookup discovery service. This 82 * ID is used to determine equality between registrations (proxies), 83 * as well as to index into the various managed sets maintained by 84 * the back-end server. 85 * 86 * @serial 87 */ 88 final Uuid registrationID; 89 /** 90 * The object which encapsulates the information used by the client 91 * to identify a notification sent by the lookup discovery service 92 * to the listener registered with the lookup discovery service by 93 * the client's registration, for which the instance of this class 94 * serves as proxy. 95 * <p> 96 * Note that it is this object that contains the lease object through 97 * which the client requests the renewal or cancellation of its 98 * registration with this service. 99 * 100 * @serial 101 */ 102 final EventRegistration eventReg; 103 104 /** 105 * Public static factory method that creates and returns an instance of 106 * <code>FiddlerRegistration</code>. If the server associated with 107 * this registration implements <code>RemoteMethodControl</code>, then the 108 * object returned by this method will also implement 109 * <code>RemoteMethodControl</code>. 110 * 111 * @param server reference to the server object through which 112 * communication occurs between the client-side and 113 * server-side of the lookup discovery service. 114 * @param registrationID the unique identifier assigned by the lookup 115 * discovery service to the current instance of 116 * this proxy 117 * @param eventReg object which encapsulates the information used 118 * by the client to identify a notification sent by 119 * the lookup discovery service to the listener 120 * registered with the lookup discovery service by 121 * the client's registration, for which the instance 122 * of this class serves as proxy. 123 * <p> 124 * It is through this object that the client requests 125 * the renewal or cancellation of the registration 126 * being constructed. 127 * 128 * @return an instance of <code>FiddlerRegistration</code> that implements 129 * <code>RemoteMethodControl</code> if the given <code>server</code> 130 * does. 131 */ 132 public static FiddlerRegistration createRegistration 133 (Fiddler server, 134 Uuid registrationID, 135 EventRegistration eventReg) 136 { 137 if(server instanceof RemoteMethodControl) { 138 return new ConstrainableFiddlerRegistration 139 (server, registrationID, eventReg, null); 140 } else { 141 return new FiddlerRegistration(server, registrationID, eventReg); 142 }//endif 143 }//end createRegistration 144 145 /** 146 * Constructs a new instance of FiddlerRegistration. 147 * 148 * @param server reference to the server object through which 149 * communication occurs between the client-side and 150 * server-side of the lookup discovery service. 151 * @param registrationID the unique identifier assigned by the lookup 152 * discovery service to the current instance of 153 * this proxy 154 * @param eventReg object which encapsulates the information used 155 * by the client to identify a notification sent by 156 * the lookup discovery service to the listener 157 * registered with the lookup discovery service by 158 * the client's registration, for which the instance 159 * of this class serves as proxy. 160 * <p> 161 * It is through this object that the client requests 162 * the renewal or cancellation of the registration 163 * being constructed. 164 */ 165 private FiddlerRegistration(Fiddler server, 166 Uuid registrationID, 167 EventRegistration eventReg) 168 { 169 this.server = server; 170 this.registrationID = registrationID; 171 this.eventReg = eventReg; 172 }//end constructor 173 174 FiddlerRegistration(GetArg arg) throws IOException { 175 this(check((Fiddler) arg.get("server", null), 176 (Uuid) arg.get("registrationID", null), 177 (EventRegistration) arg.get("eventReg", null)), 178 (Uuid) arg.get("registrationID", null), 179 (EventRegistration) arg.get("eventReg", null) 180 ); 181 } 182 183 184 /* *** Methods of net.jini.discovery.LookupDiscoveryRegistration *** */ 185 186 /** 187 * Returns an EventRegistration object that encapsulates the information 188 * needed by the client to identify a notification sent by the lookup 189 * discovery service to the registration's listener. This method is 190 * not remote and takes no arguments. 191 * 192 * @return the EventRegistration for this registration. 193 * 194 * @see 195 * net.jini.discovery.LookupDiscoveryRegistration#getEventRegistration 196 */ 197 public EventRegistration getEventRegistration() { 198 return eventReg; 199 } 200 201 /** 202 * Returns the Lease object that controls a client's registration with 203 * the lookup discovery service. It is through the object returned by 204 * this method that the client can request the renewal or cancellation 205 * of the registration with the lookup discovery service. This method is 206 * not remote and takes no arguments. 207 * 208 * @return the Lease on this registration. 209 * 210 * @see net.jini.discovery.LookupDiscoveryRegistration#getLease 211 */ 212 public Lease getLease() { 213 return eventReg.getLease(); 214 } 215 216 /** 217 * Returns an array consisting of instances of the ServiceRegistrar 218 * interface. Each element in the returned set is a proxy to one of 219 * lookup service(s) that have already been discovered for this 220 * registration. The contents of the returned set make up the 221 * 'remote state' of this registration's currently discovered lookup 222 * service(s). This method returns a new array on each invocation. 223 * <p> 224 * To obtain the desired lookup service proxies, this method sends a 225 * request to the the lookup discovery service. Upon receiving the 226 * request, the lookup discovery service sends the requested set of 227 * proxies as a set of marshalled instances of the ServiceRegistrar 228 * interface. Thus, in order to construct the return set, this method 229 * attempts to unmarshal each element of the set received from the 230 * lookup discovery service. Should a failure occur while attempting 231 * to unmarshal any of the elements of the received set of marshalled 232 * proxy objects, this method will throw an exception of type 233 * LookupUnmarshalException. 234 * <p> 235 * When a LookupUnmarshalException is thrown by this method, the 236 * contents of the exception provides the client with the following 237 * useful information: (1) the knowledge that a problem has occurred 238 * while unmarshalling at least one of the elements making up the 239 * remote state of this registration's discovered lookup service(s), 240 * (2) the set consisting of the proxy objects that were successfully 241 * unmarshalled by this method, (3) the set consisting of the marshalled 242 * proxy objects that could not be unmarshalled by this method, and 243 * (4) the set of exceptions corresponding to each failed attempt at 244 * unmarshalling. 245 * <p> 246 * Typically, the type of exception that occurs when attempting to 247 * unmarshal an element of the set of marshalled proxies is either an 248 * IOException or a ClassNotFoundException. A ClassNotFoundException 249 * occurs whenever a remote field of the marshalled proxy cannot be 250 * retrieved (usually because the codebase of one of the field's classes 251 * or interfaces is currently 'down'). To address this situation, the 252 * client may wish to proceed with its processing using the successfully 253 * unmarshalled proxies; and attempt to unmarshal the unavailable proxies 254 * (or re-invoke this method) at some later time. 255 * <p> 256 * Note that if this method returns successfully without throwing a 257 * LookupUnmarshalException, the client is guaranteed that all 258 * marshalled proxies returned to this method by the lookup discovery 259 * service have been successfully unmarshalled; and the client then 260 * has a snapshot - relative to the point in time when this method 261 * is invoked - of the remote state of the lookup service(s) discovered 262 * for this registration. 263 * 264 * @return an array of ServiceRegistrar objects. 265 * 266 * @throws net.jini.discovery.LookupUnmarshalException this exception 267 * is thrown when failure occurs while attempting to unmarshal 268 * one or more of the marshalled instances of ServiceRegistrar 269 * received from the lookup discovery service. 270 * 271 * @throws java.rmi.RemoteException typically, this exception occurs when 272 * there is a communication failure between the client and the 273 * lookup discovery service. 274 * 275 * @throws java.rmi.NoSuchObjectException whenever the referenced 276 * registration is invalid or non-existent. 277 * 278 * @see net.jini.discovery.LookupDiscoveryRegistration#getRegistrars 279 */ 280 public ServiceRegistrar[] getRegistrars() throws LookupUnmarshalException, 281 RemoteException 282 { 283 MarshalledObject[] mRegs = null; 284 try { 285 mRegs = server.getRegistrars(registrationID); 286 } catch (ThrowThis e) { 287 e.throwRemoteException(); 288 } 289 if (mRegs == null) return null; 290 291 ServiceRegistrar[] regs = new ServiceRegistrar[mRegs.length]; 292 if(regs.length > 0) { 293 ArrayList marshalledRegs = new ArrayList(); 294 for(int i=0;i<mRegs.length;i++) marshalledRegs.add(mRegs[i]); 295 ArrayList unmarshalledRegs = new ArrayList(); 296 ArrayList exceptions = unmarshalRegistrars(marshalledRegs, 297 unmarshalledRegs); 298 /* Add the un-marshalled elements to the end of regs */ 299 insertRegistrars(regs,unmarshalledRegs); 300 if( exceptions.size() > 0 ) { 301 throw(new LookupUnmarshalException 302 ( (ServiceRegistrar[])(unmarshalledRegs.toArray 303 (new ServiceRegistrar[unmarshalledRegs.size()])), 304 (MarshalledObject[])(marshalledRegs.toArray 305 (new MarshalledObject[marshalledRegs.size()])), 306 (Throwable[])(exceptions.toArray 307 (new Throwable[exceptions.size()])), 308 "failed to unmarshal at least one ServiceRegistrar") ); 309 }//endif 310 } else { 311 return regs; 312 }//endif 313 314 /* Remove duplicates */ 315 HashSet regsCopy = new HashSet(); // no duplicates 316 for(int i=0;i<regs.length;i++) { 317 if(regs[i] == null) continue; 318 regsCopy.add(regs[i]); 319 }//endloop 320 321 return ( (ServiceRegistrar[])(regsCopy).toArray 322 (new ServiceRegistrar[regsCopy.size()]) ); 323 } 324 325 /** 326 * Returns an array consisting of the names of the groups whose members 327 * are lookup services the lookup discovery service will attempt to 328 * discover for the registration corresponding to the current instance 329 * of this class. This set of group names is referred to as the 330 * registration's 'managed set of groups'. 331 * <p> 332 * If the registration's managed set of groups is currently empty, then 333 * the empty array is returned. If the lookup discovery service currently 334 * has no managed set of groups for the registration through which the 335 * request is being made, then null will be returned. 336 * 337 * @return a String array containing the elements of the managed set of 338 * groups for the registration. 339 * 340 * @throws java.rmi.RemoteException typically, this exception occurs when 341 * there is a communication failure between the client and the 342 * lookup discovery service. 343 * 344 * @throws java.rmi.NoSuchObjectException whenever the 345 * <code>registrationID</code> parameter references an invalid 346 * or non-existent registration. 347 * 348 * @see net.jini.discovery.LookupDiscoveryRegistration#getGroups 349 */ 350 public String[] getGroups() throws RemoteException { 351 try { 352 return server.getGroups(registrationID); 353 } catch (ThrowThis e) { 354 e.throwRemoteException(); 355 } 356 return new String[0]; 357 } 358 359 /** 360 * Returns an array consisting of the the LookupLocator objects 361 * corresponding to specific lookup services the lookup discovery 362 * service will attempt to discover for for the registration 363 * corresponding to the current instance of this class. This set of 364 * locators is referred to as the registration's 'managed set of locators'. 365 * <p> 366 * If the registration's managed set of locators is currently empty, then 367 * the empty array is returned. If the lookup discovery service currently 368 * has no managed set of locators for the registration through which the 369 * request is being made, then null will be returned. 370 * 371 * @return array consisting of net.jini.core.discovery.LookupLocator 372 * objects corresponding to the elements of the managed set of 373 * locators for the registration. 374 * 375 * @throws java.rmi.RemoteException typically, this exception occurs when 376 * there is a communication failure between the client and the 377 * lookup discovery service. 378 * 379 * @throws java.rmi.NoSuchObjectException whenever the 380 * <code>registrationID</code> parameter references an invalid 381 * or non-existent registration. 382 * 383 * @see net.jini.discovery.LookupDiscoveryRegistration#getLocators 384 */ 385 public LookupLocator[] getLocators() throws RemoteException { 386 try { 387 return server.getLocators(registrationID); 388 } catch (ThrowThis e) { 389 e.throwRemoteException(); 390 } 391 return null; 392 } 393 394 /** 395 * Adds a set of group names to the managed set of groups associated 396 * with the registration corresponding to the current instance of 397 * this class. 398 * 399 * @param groups a String array, none of whose elements may be null, 400 * consisting of the group names with which to augment 401 * the registration's managed set of groups. 402 * <p> 403 * If any element of this parameter duplicates any other 404 * element of this parameter, the duplicate will be ignored. 405 * If any element of this parameter duplicates any element 406 * of the registration's current managed set of groups, the 407 * duplicate will be ignored. 408 * <p> 409 * If the empty set is input, then the registration's 410 * managed set of groups will not change. If null is 411 * input, this method will throw a NullPointerException. 412 * 413 * @throws java.lang.UnsupportedOperationException this exception occurs 414 * when the lookup discovery service has no managed set of groups 415 * associated with the registration. 416 * 417 * @throws java.lang.NullPointerException this exception occurs when 418 * either null is input to the groups parameter, or one or more 419 * of the elements of the groups parameter is null. 420 * 421 * @throws java.rmi.RemoteException typically, this exception occurs when 422 * there is a communication failure between the client and the 423 * lookup discovery service. When this exception does occur, the 424 * registration's managed set of groups may or may not have been 425 * successfully augmented. 426 * 427 * @throws java.rmi.NoSuchObjectException whenever the 428 * <code>registrationID</code> parameter references an invalid 429 * or non-existent registration. 430 * 431 * @see net.jini.discovery.LookupDiscoveryRegistration#addGroups 432 */ 433 public void addGroups(String[] groups) throws RemoteException { 434 try { 435 server.addGroups(registrationID,groups); 436 } catch (ThrowThis e) { 437 e.throwRemoteException(); 438 } 439 } 440 441 /** 442 * Replaces all of the group names in the managed set of groups 443 * associated with the registration corresponding to the current 444 * instance of this class. 445 * 446 * @param groups a String array, none of whose elements may be null, 447 * consisting of the group names with which to replace the 448 * names in this registration's managed set of groups. 449 * <p> 450 * If any element of this parameter duplicates any other 451 * element of this parameter, the duplicate will be ignored. 452 * <p> 453 * If the empty set is input, then group discovery for 454 * the registration will cease. If null is input, the 455 * lookup discovery service will attempt to discover all 456 * as yet undiscovered lookup services located within its 457 * multicast radius and, upon discovery of any such lookup 458 * service, will send to the registration's listener an 459 * event signaling that discovery. 460 * 461 * @throws java.lang.NullPointerException this exception occurs when one 462 * or more of the elements of the groups parameter is null. 463 * 464 * @throws java.rmi.RemoteException typically, this exception occurs when 465 * there is a communication failure between the client and the 466 * lookup discovery service. When this exception does occur, the 467 * registration's managed set of groups may or may not have been 468 * successfully replaced. 469 * 470 * @throws java.rmi.NoSuchObjectException whenever the 471 * <code>registrationID</code> parameter references an invalid 472 * or non-existent registration. 473 * 474 * @see net.jini.discovery.LookupDiscoveryRegistration#setGroups 475 */ 476 public void setGroups(String[] groups) throws RemoteException { 477 try { 478 server.setGroups(registrationID,groups); 479 } catch (ThrowThis e) { 480 e.throwRemoteException(); 481 } 482 } 483 484 /** 485 * Deletes a set of group names from the managed set of groups 486 * associated with the registration corresponding to the current 487 * instance of this class. 488 * 489 * @param groups a String array, none of whose elements may be null, 490 * consisting of the group names to delete from the 491 * registration's managed set of groups. 492 * <p> 493 * If any element of this parameter duplicates any other 494 * element of this parameter, the duplicate will be ignored. 495 * <p> 496 * If the empty set is input, the registration's managed 497 * set of groups will not change. If null is input, this 498 * method will throw a NullPointerException. 499 * 500 * @throws java.lang.UnsupportedOperationException this exception occurs 501 * when the lookup discovery service has no managed set of groups 502 * associated with the registration. 503 * 504 * @throws java.lang.NullPointerException this exception occurs when 505 * either null is input to the groups parameter, or one or more 506 * of the elements of the groups parameter is null. 507 * 508 * @throws java.rmi.RemoteException typically, this exception occurs when 509 * there is a communication failure between the client and the 510 * lookup discovery service. When this exception does occur, the 511 * registration's managed set of groups may or may not have been 512 * successfully modified. 513 * 514 * @throws java.rmi.NoSuchObjectException whenever the 515 * <code>registrationID</code> parameter references an invalid 516 * or non-existent registration. 517 * 518 * @see net.jini.discovery.LookupDiscoveryRegistration#removeGroups 519 */ 520 public void removeGroups(String[] groups) throws RemoteException { 521 try { 522 server.removeGroups(registrationID,groups); 523 } catch (ThrowThis e) { 524 e.throwRemoteException(); 525 } 526 } 527 528 /** 529 * Adds a set of LookupLocator objects to the managed set of locators 530 * associated with the registration corresponding to the current 531 * instance of this class. 532 * 533 * @param locators an array, none of whose elements may be null, consisting 534 * of the LookupLocator objects with which to augment 535 * the registration's managed set of locators. 536 * <p> 537 * If any element of this parameter duplicates any other 538 * element of this parameter, the duplicate will be 539 * ignored. If any element of this parameter duplicates 540 * any element of the registration's managed set of 541 * locators, the duplicate will be ignored. 542 * <p> 543 * If the empty array is input, then the registration's 544 * managed set of locators will not change. If null is 545 * input, this method will throw a NullPointerException. 546 * 547 * @throws java.lang.UnsupportedOperationException this exception occurs 548 * when the lookup discovery service has no managed set of 549 * locators associated with the registration. 550 * 551 * @throws java.lang.NullPointerException this exception occurs when 552 * either null is input to the locators parameter, or one or 553 * more of the elements of the locators parameter is null. 554 * 555 * @throws java.rmi.RemoteException typically, this exception occurs when 556 * there is a communication failure between the client and the 557 * lookup discovery service. When this exception does occur, the 558 * registration's managed set of locators may or may not have 559 * been successfully augmented. 560 * 561 * @throws java.rmi.NoSuchObjectException whenever the 562 * <code>registrationID</code> parameter references an invalid 563 * or non-existent registration. 564 * 565 * @see net.jini.discovery.LookupDiscoveryRegistration#addLocators 566 */ 567 public void addLocators(LookupLocator[] locators) throws RemoteException { 568 try { 569 server.addLocators(registrationID,locators); 570 } catch (ThrowThis e) { 571 e.throwRemoteException(); 572 } 573 } 574 575 /** 576 * Replaces with a new set of LookupLocator objects, all of the 577 * elements in the managed set of locators associated with the 578 * registration corresponding to the current instance of this class. 579 * 580 * @param locators an array, none of whose elements may be null, consisting 581 * of the LookupLocator objects with which to replace the 582 * locators in the registration's managed set of locators. 583 * <p> 584 * If any element of this parameter duplicates any other 585 * element of this parameter, the duplicate will be 586 * ignored. 587 * <p> 588 * If the empty array is input, then locator discovery for 589 * the registration will cease. If null is input, this 590 * method will throw a NullPointerException. 591 * 592 * @throws java.lang.NullPointerException this exception occurs when 593 * either null is input to the locators parameter, or one or 594 * more of the elements of the locators parameter is null. 595 * 596 * @throws java.rmi.RemoteException typically, this exception occurs when 597 * there is a communication failure between the client and the 598 * lookup discovery service. When this exception does occur, the 599 * registration's managed set of locators may or may not have 600 * been successfully replaced. 601 * 602 * @throws java.rmi.NoSuchObjectException whenever the 603 * <code>registrationID</code> parameter references an invalid 604 * or non-existent registration. 605 * 606 * @see net.jini.discovery.LookupDiscoveryRegistration#setLocators 607 */ 608 public void setLocators(LookupLocator[] locators) throws RemoteException { 609 try { 610 server.setLocators(registrationID,locators); 611 } catch (ThrowThis e) { 612 e.throwRemoteException(); 613 } 614 } 615 616 /** 617 * Deletes a set of LookupLocator objects from the managed set of 618 * locators associated with the registration corresponding to the 619 * current instance of this class. 620 * 621 * @param locators an array, none of whose elements may be null, consisting 622 * of the LookupLocator objects to remove from the 623 * registration's managed set of locators. 624 * <p> 625 * If any element of this parameter duplicates any other 626 * element of this parameter, the duplicate will be 627 * ignored. 628 * <p> 629 * If the empty set is input, the managed set of locators 630 * will not change. If null is input, this method will 631 * throw a NullPointerException. 632 * 633 * @throws java.lang.UnsupportedOperationException this exception occurs 634 * when the lookup discovery service has no managed set of 635 * locators associated with the registration. 636 * 637 * @throws java.lang.NullPointerException this exception occurs when 638 * either null is input to the locators parameter, or one or 639 * more of the elements of the locators parameter is null. 640 * 641 * @throws java.rmi.RemoteException typically, this exception occurs when 642 * there is a communication failure between the client and the 643 * lookup discovery service. When this exception does occur, the 644 * registration's managed set of locators may or may not have 645 * been successfully modified. 646 * 647 * @throws java.rmi.NoSuchObjectException whenever the 648 * <code>registrationID</code> parameter references an invalid 649 * or non-existent registration. 650 * 651 * @see net.jini.discovery.LookupDiscoveryRegistration#removeLocators 652 */ 653 public void removeLocators(LookupLocator[] locators) throws RemoteException 654 { 655 try { 656 server.removeLocators(registrationID,locators); 657 } catch (ThrowThis e) { 658 e.throwRemoteException(); 659 } 660 } 661 662 /** 663 * Informs the lookup discovery service of the existence of an 664 * unavailable lookup service and requests that the lookup discovery 665 * service discard the unavailable lookup service. 666 * 667 * @param registrar a reference to the lookup service that the lookup 668 * discovery service is being asked to discard. 669 * <p> 670 * If this parameter equals none of the lookup services 671 * contained in the managed set of lookup services for 672 * this registration, no action will be taken. 673 * 674 * @throws java.lang.NullPointerException this exception occurs when 675 * null is input to the registrar parameter. 676 * 677 * @throws java.rmi.RemoteException typically, this exception occurs when 678 * there is a communication failure between the client and the 679 * lookup discovery service. When this exception does occur, 680 * the lookup service may or may not have been successfully 681 * discarded. 682 * 683 * @throws java.rmi.NoSuchObjectException whenever the 684 * <code>registrationID</code> parameter references an invalid 685 * or non-existent registration. 686 * 687 * @see net.jini.discovery.LookupDiscoveryRegistration#discard 688 */ 689 public void discard(ServiceRegistrar registrar) throws RemoteException { 690 try { 691 server.discard(registrationID,registrar); 692 } catch (ThrowThis e) { 693 e.throwRemoteException(); 694 } 695 } 696 697 /* From net.jini.id.ReferentUuid */ 698 699 /** 700 * Returns the universally unique identifier that has been assigned to the 701 * resource this proxy represents. 702 * 703 * @return the instance of <code>Uuid</code> that is associated with the 704 * resource this proxy represents. This method will not return 705 * <code>null</code>. 706 * 707 * @see net.jini.id.ReferentUuid 708 */ 709 public Uuid getReferentUuid() { 710 return registrationID; 711 } 712 713 /* *** hashCode and Equals for this class *** */ 714 715 /** 716 * For any instance of this class, returns the hashcode value generated 717 * by the hashCode method of the registration ID associated with the 718 * current instance of this proxy. 719 * 720 * @return <code>int</code> value representing the hashcode for an 721 * instance of this class. 722 */ 723 public int hashCode() { 724 return registrationID.hashCode(); 725 } 726 727 /** 728 * For any instance of this class, indicates whether the object input 729 * to this method is equal to the current instance of this class; where 730 * equality of proxies to a registration with a lookup discovery service 731 * is defined by reference equality. That is, two proxies are equal if 732 * they reference (are proxies to) the same backend server. 733 * 734 * @param obj reference to the object that is to be compared to the 735 * object on which this method is invoked. 736 * 737 * @return <code>true</code> if the object input is referentially 738 * equal to the object on which this method is invoked; 739 * <code>false</code> otherwise. 740 */ 741 public boolean equals(Object obj) { 742 return ReferentUuids.compare(this,obj); 743 } 744 745 /** 746 * Attempts to unmarshal each element of the first input argument. When 747 * an element of that argument is successfully unmarshalled, that element 748 * is removed from the first set and the resulting unmarshalled proxy 749 * is placed in the set referenced by the second input argument. 750 * Whenever failure occurs as a result of an attempt to unmarshal one 751 * of the elements of the first set, the exception that is thrown as 752 * as a result of that failure is placed in the returned set of 753 * exceptions. 754 * <p> 755 * Note that there is a one-to-one correspondence between the exceptions 756 * contained in the return set and the remaining elements in the first 757 * set after all unmarshalling attempts have completed. 758 * 759 * @param marshalledRegs an ArrayList object consisting of marshalled 760 * instances of ServiceRegistrar, each 761 * corresponding to a proxy to a lookup service. 762 * 763 * @param unmarshalledRegs an ArrayList object consisting of all 764 * successfully unmarshalled proxies from 765 * the first argument. 766 * 767 * @return an ArrayList consisting of the exceptions that occur as a 768 * result of attempts to unmarshal each element of the first 769 * argument to this method. 770 */ 771 private static ArrayList unmarshalRegistrars(ArrayList marshalledRegs, 772 ArrayList unmarshalledRegs) 773 { 774 ArrayList exceptions = new ArrayList(); 775 /* Try to un-marshal the current element in the set of marshalled regs. 776 * 777 * If current element is successfully un-marshalled: 778 * -- record the un-marshalled element 779 * -- delete the corresponding marshalled element from its set 780 * 781 * If current element cannot be un-marshalled: 782 * -- record the exception 783 * -- leave the corresponding marshalled element in its set 784 * -- increment the index to the next marshalled element 785 */ 786 int i = 0; 787 int nMarshalledRegs = marshalledRegs.size(); 788 for(int n=0;n<nMarshalledRegs;n++) { 789 try { 790 /* Try to un-marshal the current element in marshalledRegs */ 791 792 /* Note that index 'n' is only a counter. That is, it is 793 * intentional that the element at index 'i' is the element 794 * that is unmarshalled, not the element at index 'n'. 795 * This is because whenever the element is successfully 796 * unmarshalled, the element is removed from the set of 797 * marshalled registrars, decreasing that set by 1 element. 798 * Thus, the 'next' element to unmarshal is actually at 799 * the same index as the last element that was unmarshalled. 800 */ 801 MarshalledObject marshalledObj 802 = (MarshalledObject)(marshalledRegs.get(i)); 803 ServiceRegistrar reg = (ServiceRegistrar)( 804 new MarshalledInstance(marshalledObj).get(false)); 805 /* Success: record the un-marshalled element 806 * delete the corresponding un-marshalled element 807 */ 808 unmarshalledRegs.add( reg ); 809 marshalledRegs.remove(i); 810 } catch(IOException e) { 811 exceptions.add(e); 812 i=i+1; 813 } catch(ClassNotFoundException e) { 814 exceptions.add(e); 815 i=i+1; 816 } 817 } 818 return exceptions; 819 } 820 821 /** 822 * Places the the lookup service reference(s), contained in the input 823 * ArrayList, into the 'empty' slots occurring at the end (indicated 824 * by the first null element) of the input array. 825 * 826 * @param regsArray array that will receive the new references. 827 * 828 * @param regsList ArrayList containing the ServiceRegistrar references 829 * to place in regsArray input argument. 830 */ 831 private static void insertRegistrars(ServiceRegistrar[] regsArray, 832 ArrayList regsList) 833 { 834 if((regsArray != null) && (regsList != null)) { 835 int lenA = regsArray.length; 836 int lenB = regsList.size(); 837 if((lenA == 0) || (lenB == 0)) return; 838 int beg = indexFirstNull(regsArray); 839 int end = ( (beg+lenB) <= lenA ? (beg+lenB) : (lenA) ); 840 for(int i=beg, j=0; i<end; i++,j++) { 841 regsArray[i] = (ServiceRegistrar)(regsList.get(j)); 842 } 843 } 844 } 845 846 /** 847 * Finds the index of the first element in the input array that contains 848 * null. 849 * <p> 850 * If the array is null (or has zero length), -1 will be returned. If 851 * every element of the array is non-null, this method will return 852 * the length of the array. Thus, after invoking this method, it is 853 * important to test for these conditions to avoid the occurrence of an 854 * IndexOutOfBoundsException when using the value returned by this 855 * method. 856 * 857 * @param arr Object array to examine for the first occurrence of null 858 * 859 * @return the index of the first element in the input array that contains 860 * null. A value of -1 is returned if the input array is null; 861 * the length of the array is returned if no element in the 862 * array is null. 863 */ 864 private static int indexFirstNull(Object[] arr) { 865 int i = -1; 866 if( (arr == null) || (arr.length == 0) ) return i; 867 for(i=0;i<arr.length;i++) { 868 if(arr[i] == null) return i; 869 } 870 return i; 871 } 872 873 /** When an instance of this class is deserialized, this method is 874 * automatically invoked. This implementation of this method validates 875 * the state of the deserialized instance. 876 * 877 * @throws InvalidObjectException if the state of the 878 * deserialized instance of this class is found to be invalid. 879 */ 880 private void readObject(ObjectInputStream s) 881 throws IOException, ClassNotFoundException 882 { 883 s.defaultReadObject(); 884 885 /* Verify server */ 886 if(server == null) { 887 throw new InvalidObjectException 888 ("FiddlerRegistration.readObject " 889 +"failure - server field is null"); 890 }//endif 891 892 /* Verify registrationID */ 893 if(registrationID == null) { 894 throw new InvalidObjectException 895 ("FiddlerRegistration.readObject " 896 +"failure - registrationID field is null"); 897 }//endif 898 899 /* Verify eventReg and its contents */ 900 if(eventReg == null) { 901 throw new InvalidObjectException 902 ("FiddlerRegistration.readObject " 903 +"failure - eventReg field is null"); 904 }//endif 905 /* Verify eventReg is not a subclass EventRegistration */ 906 if( !((EventRegistration.class).equals(eventReg.getClass())) ) { 907 throw new InvalidObjectException 908 ("ConstrainableFiddlerRegistration.readObject " 909 +"failure - eventReg class is not " 910 +"EventRegistration"); 911 }//endif 912 /* Verify eventReg.source */ 913 Object source = eventReg.getSource(); 914 if(source == null) { 915 throw new InvalidObjectException 916 ("FiddlerRegistration.readObject " 917 +"failure - eventReg source is null"); 918 }//endif 919 if( !(source instanceof FiddlerProxy) ) { 920 throw new InvalidObjectException 921 ("FiddlerRegistration.readObject failure - " 922 +"eventReg source is not an instance of " 923 +"FiddlerProxy"); 924 }//endif 925 /* source.server != null was verified in FiddlerProxy.readObject() */ 926 927 /* Verify eventReg.lease */ 928 Object lease = eventReg.getLease(); 929 if( !(lease instanceof FiddlerLease) ) { 930 throw new InvalidObjectException 931 ("FiddlerRegistration.readObject failure - " 932 +"eventReg lease is not an instance of " 933 +"FiddlerLease"); 934 }//endif 935 /* lease.server != null was verified in FiddlerLease.readObject() */ 936 937 }//end readObject 938 939 private static Fiddler check(Fiddler server, 940 Uuid registrationID, 941 EventRegistration eventReg) 942 throws InvalidObjectException 943 { 944 /* Verify server */ 945 if(server == null) { 946 throw new InvalidObjectException 947 ("FiddlerRegistration.readObject " 948 +"failure - server field is null"); 949 }//endif 950 951 /* Verify registrationID */ 952 if(registrationID == null) { 953 throw new InvalidObjectException 954 ("FiddlerRegistration.readObject " 955 +"failure - registrationID field is null"); 956 }//endif 957 958 /* Verify eventReg and its contents */ 959 if(eventReg == null) { 960 throw new InvalidObjectException 961 ("FiddlerRegistration.readObject " 962 +"failure - eventReg field is null"); 963 }//endif 964 /* Verify eventReg is not a subclass EventRegistration */ 965 if( !((EventRegistration.class).equals(eventReg.getClass())) ) { 966 throw new InvalidObjectException 967 ("ConstrainableFiddlerRegistration.readObject " 968 +"failure - eventReg class is not " 969 +"EventRegistration"); 970 }//endif 971 /* Verify eventReg.source */ 972 Object source = eventReg.getSource(); 973 if(source == null) { 974 throw new InvalidObjectException 975 ("FiddlerRegistration.readObject " 976 +"failure - eventReg source is null"); 977 }//endif 978 if( !(source instanceof FiddlerProxy) ) { 979 throw new InvalidObjectException 980 ("FiddlerRegistration.readObject failure - " 981 +"eventReg source is not an instance of " 982 +"FiddlerProxy"); 983 }//endif 984 /* source.server != null was verified in FiddlerProxy.readObject() */ 985 986 /* Verify eventReg.lease */ 987 Object lease = eventReg.getLease(); 988 if( !(lease instanceof FiddlerLease) ) { 989 throw new InvalidObjectException 990 ("FiddlerRegistration.readObject failure - " 991 +"eventReg lease is not an instance of " 992 +"FiddlerLease"); 993 }//endif 994 /* lease.server != null was verified in FiddlerLease.readObject() */ 995 996 return server; 997 } 998 999 /** During deserialization of an instance of this class, if it is found 1000 * that the stream contains no data, this method is automatically 1001 * invoked. Because it is expected that the stream should always 1002 * contain data, this implementation of this method simply declares 1003 * that something must be wrong. 1004 * 1005 * @throws InvalidObjectException to indicate that there 1006 * was no data in the stream during deserialization of an 1007 * instance of this class; declaring that something is wrong. 1008 */ 1009 private void readObjectNoData() throws InvalidObjectException { 1010 throw new InvalidObjectException("no data found when attempting to " 1011 +"deserialize FiddlerRegistration " 1012 +"instance"); 1013 }//end readObjectNoData 1014 1015 /** The constrainable version of <code>FiddlerRegistration</code>. 1016 * <p> 1017 * When a client obtains an instance of this proxy class, the client 1018 * should not attempt to use the proxy until the client is assured 1019 * that the proxy can be trusted. In addition to implementing the 1020 * methods and mechanisms required by <code>RemoteMethodControl</code>, 1021 * this class - in conjunction with the service's 1022 * <code>ProxyVerifier</code> class, helps provide a mechanism 1023 * for verifying trust in the proxy on behalf of a client. 1024 * <p> 1025 * In order to verify that an instance of this class is trusted, 1026 * trust must be verified in all subsidiary objects (contained in that 1027 * instance) through which the client ultimately makes calls (local or 1028 * remote). With respect to this class, the <code>server</code> field 1029 * (which will be referred to as 'server1' for this description) is 1030 * a proxy object through which the client makes remote calls to the 1031 * service's backend. Therefore, trust in that object must be 1032 * verified. 1033 * <p> 1034 * In addition to server1, this class also contains a field of 1035 * type <code>Uuid</code> (<code>registrationID</code>), and a 1036 * field of type <code>EventRegistration</code> (the field 1037 * <code>eventReg</code>). Therefore, as with server1, trust must 1038 * also be verified in each of these objects. 1039 * <p> 1040 * As indicated by the pattern described above, in order to verify 1041 * trust in the subsidiary objects of this class, trust must also be 1042 * verified in any subsidiary objects those objects themselves 1043 * contain; and so on, until all subsidiary objects have been 1044 * exhausted. The <code>eventReg</code> field contains such subsidiary 1045 * objects that also contain subsidiary objects, each requiring 1046 * verification. Those subsidiary objects are: a field of type 1047 * <code>ConstrainableFiddlerProxy</code> (named <code>source</code>), 1048 * and a field of type <code>ConstrainableFiddlerLease</code> 1049 * (the field named <code>lease</code>, referred to below as 'lease1'). 1050 * <p> 1051 * As with this class, the <code>source</code> field of 1052 * <code>eventReg</code> is also an "outer proxy" to the service's 1053 * backend, and thus also contains an (inner) proxy object (referred 1054 * to below as 'server2') through which remote calls are made to the 1055 * service's backend; thus, server2 must be verified. And since 1056 * the <code>lease</code> field of <code>eventReg</code> also contains 1057 * an (inner) proxy object ('server3'), that subsidiary object must 1058 * be verified as well. 1059 * <p> 1060 * The description above is summarized in the following diagram: 1061 * <p> 1062 * <pre> 1063 * FiddlerRegistration { 1064 * Fiddler server1 1065 * Uuid registrationID 1066 * EventRegistration eventReg { 1067 * ConstrainableFiddlerProxy source { 1068 * Fiddler server2 1069 * }//end source 1070 * ConstrainableFiddlerLease lease { 1071 * Fiddler server3 1072 * }//end lease 1073 * }//end eventReg 1074 * }//end FiddlerRegistration 1075 * </pre> 1076 * <p> 1077 * Thus, in order to verify that an instance of this class is trusted, 1078 * trust must be verified in the following objects from the diagram 1079 * above: 1080 * <ul><li> server1 1081 * <li> registrationID 1082 * <li> eventReg 1083 * <ul><li> source 1084 * <ul><li> server2</ul> 1085 * <li> lease 1086 * <ul><li> server3</ul> 1087 * </ul> 1088 * </ul> 1089 * 1090 * When a client obtains an instance of this proxy class, the 1091 * deserialization process which delivers the proxy to the client 1092 * invokes the <code>readObject</code> method of this class, as well 1093 * as the <code>readObject</code> method for each subsidiary object, 1094 * as the mechanism "walks" through the serialization graph. For 1095 * each object that must be verified, part of that trust verification 1096 * process is performed in the various <code>readObject</code> methods, 1097 * and the remaining part is performed when the client prepares 1098 * the proxy. This class' participation in the trust verification 1099 * process can be summarized as follows: 1100 * <p> 1101 * <ul> 1102 * <li> server1 1103 * <ul> 1104 * <li> readObject 1105 * <ul> 1106 * <li> verify server1 != null 1107 * <li> verify registrationID != null 1108 * <li> verify eventReg != null 1109 * <li> verify eventReg is an instance of EventRegistration, but 1110 * NOT a subclass of EventRegistration (if it's a subclass, 1111 * then it's possible that the subclass contains methods 1112 * that override the methods of EventRegistration with 1113 * untrusted, un-constrained implementations) 1114 * <li> verify eventReg.source != null 1115 * <li> verify eventReg.source is an instance of FiddlerProxy 1116 * <li> verify server2 != null (this is done in the readObject() 1117 * of FiddlerProxy) 1118 * <li> verify eventReg.lease is an instance of FiddlerLease 1119 * <li> verify server3 != null (this is done in the readObject() 1120 * of FiddlerLease) 1121 * 1122 * <li> verify server1 implements RemoteMethodControl 1123 * <li> verify server1's method constraints are the same 1124 * as those placed on the corresponding public Remote 1125 * methods of its outer proxy class 1126 * 1127 * <li> verify eventReg.source is an instance of 1128 * ConstrainableFiddlerProxy 1129 * 1130 * <li> verify lease is instance of ConstrainableFiddlerLease 1131 * </ul> 1132 * <li> proxy preparation 1133 * <ul> 1134 * <li> Security.verifyObjectTrust() which calls 1135 * <li> ProxyVerifier.isTrustedObject(this) which calls 1136 * <ul> 1137 * <li> ProxyVerifier.isTrustedObject(source) which calls 1138 * canonicalServerObject.checkTrustEquivalence(server2) 1139 * <li> ProxyVerifier.isTrustedObject(lease) which calls 1140 * canonicalServerObject.checkTrustEquivalence(server3) 1141 * <li> canonicalServerObject.checkTrustEquivalence(server1) 1142 * (whose implementation is supplied by the particular 1143 * RMI implementation that was used to export the server) 1144 * </ul> 1145 * </ul> 1146 * </ul> 1147 * </ul> 1148 * 1149 * @since 2.0 1150 */ 1151 @AtomicSerial 1152 static final class ConstrainableFiddlerRegistration 1153 extends FiddlerRegistration 1154 implements RemoteMethodControl 1155 { 1156 static final long serialVersionUID = 2L; 1157 1158 /* Array containing element pairs in which each pair of elements 1159 * represents a correspondence 'mapping' between two methods having 1160 * the following characteristics: 1161 * - the first element in the pair is one of the public, remote 1162 * method(s) that may be invoked by the client through the proxy 1163 * class that this class extends 1164 * - the second element in the pair is the method, implemented 1165 * in the backend server class, that is ultimately executed in 1166 * the server's backend when the client invokes the corresponding 1167 * method in this proxy 1168 */ 1169 private static final Method[] methodMapArray = 1170 { 1171 ProxyUtil.getMethod(LookupDiscoveryRegistration.class, 1172 "getRegistrars", new Class[] {} ), 1173 ProxyUtil.getMethod(Fiddler.class, 1174 "getRegistrars", 1175 new Class[] {Uuid.class} ), 1176 1177 ProxyUtil.getMethod(LookupDiscoveryRegistration.class, 1178 "getGroups", new Class[] {} ), 1179 ProxyUtil.getMethod(Fiddler.class, 1180 "getGroups", 1181 new Class[] {Uuid.class} ), 1182 1183 ProxyUtil.getMethod(LookupDiscoveryRegistration.class, 1184 "getLocators", new Class[] {} ), 1185 ProxyUtil.getMethod(Fiddler.class, 1186 "getLocators", 1187 new Class[] {Uuid.class} ), 1188 1189 ProxyUtil.getMethod(LookupDiscoveryRegistration.class, 1190 "addGroups", 1191 new Class[] {String[].class} ), 1192 ProxyUtil.getMethod(Fiddler.class, 1193 "addGroups", 1194 new Class[] {Uuid.class, 1195 String[].class} ), 1196 1197 ProxyUtil.getMethod(LookupDiscoveryRegistration.class, 1198 "setGroups", 1199 new Class[] {String[].class} ), 1200 ProxyUtil.getMethod(Fiddler.class, 1201 "setGroups", 1202 new Class[] {Uuid.class, 1203 String[].class} ), 1204 1205 ProxyUtil.getMethod(LookupDiscoveryRegistration.class, 1206 "removeGroups", 1207 new Class[] {String[].class} ), 1208 ProxyUtil.getMethod(Fiddler.class, 1209 "removeGroups", 1210 new Class[] {Uuid.class, 1211 String[].class} ), 1212 1213 ProxyUtil.getMethod(LookupDiscoveryRegistration.class, 1214 "addLocators", 1215 new Class[] {LookupLocator[].class} ), 1216 ProxyUtil.getMethod(Fiddler.class, 1217 "addLocators", 1218 new Class[] {Uuid.class, 1219 LookupLocator[].class} ), 1220 1221 ProxyUtil.getMethod(LookupDiscoveryRegistration.class, 1222 "setLocators", 1223 new Class[] {LookupLocator[].class} ), 1224 ProxyUtil.getMethod(Fiddler.class, 1225 "setLocators", 1226 new Class[] {Uuid.class, 1227 LookupLocator[].class} ), 1228 1229 ProxyUtil.getMethod(LookupDiscoveryRegistration.class, 1230 "removeLocators", 1231 new Class[] {LookupLocator[].class} ), 1232 ProxyUtil.getMethod(Fiddler.class, 1233 "removeLocators", 1234 new Class[] {Uuid.class, 1235 LookupLocator[].class} ), 1236 1237 ProxyUtil.getMethod(LookupDiscoveryRegistration.class, 1238 "discard", 1239 new Class[] {ServiceRegistrar.class} ), 1240 ProxyUtil.getMethod(Fiddler.class, 1241 "discard", 1242 new Class[] {Uuid.class, 1243 ServiceRegistrar.class} ) 1244 };//end methodMapArray 1245 1246 /** Client constraints placed on this proxy (may be <code>null</code>). 1247 * 1248 * @serial 1249 */ 1250 private MethodConstraints methodConstraints; 1251 1252 /** Constructs a new <code>ConstrainableFiddlerRegistration</code> 1253 * instance. 1254 * <p> 1255 * For a description of all but the <code>methodConstraints</code> 1256 * argument (provided below), refer to the description for the 1257 * constructor of this class' super class. 1258 * 1259 * @param methodConstraints the client method constraints to place on 1260 * this proxy (may be <code>null</code>). 1261 */ 1262 private ConstrainableFiddlerRegistration 1263 (Fiddler server, 1264 Uuid registrationID, 1265 EventRegistration eventReg, 1266 MethodConstraints methodConstraints) 1267 { 1268 super( constrainServer(server, methodConstraints), 1269 registrationID, 1270 eventReg); 1271 this.methodConstraints = methodConstraints; 1272 }//end constructor 1273 1274 ConstrainableFiddlerRegistration(GetArg arg) throws IOException { 1275 super(check(arg)); 1276 methodConstraints 1277 = (MethodConstraints) arg.get("methodConstraints", null); 1278 } 1279 1280 private static GetArg check(GetArg arg) throws IOException { 1281 FiddlerRegistration fr = new FiddlerRegistration(arg); 1282 MethodConstraints methodConstraints 1283 = (MethodConstraints) arg.get("methodConstraints", null); 1284 /* Verify server1 constraints */ 1285 ConstrainableProxyUtil.verifyConsistentConstraints 1286 (methodConstraints, 1287 fr.server, 1288 methodMapArray); 1289 1290 /* Verify server3 constraints */ 1291 Object source = fr.eventReg.getSource(); 1292 if( !(source instanceof FiddlerProxy.ConstrainableFiddlerProxy) ) { 1293 throw new InvalidObjectException 1294 ("ConstrainableFiddlerRegistration.readObject " 1295 +"failure - eventReg source is not an instance " 1296 +" of ConstrainableFiddlerProxy"); 1297 }//endif 1298 /* Verify server4 constraints */ 1299 Object lease = fr.eventReg.getLease(); 1300 if( !(lease instanceof FiddlerLease.ConstrainableFiddlerLease) ) { 1301 throw new InvalidObjectException 1302 ("ConstrainableFiddlerRegistration.readObject " 1303 +"failure - eventReg lease is not an instance " 1304 +" of ConstrainableFiddlerLease"); 1305 }//endif 1306 return arg; 1307 } 1308 1309 /** Returns a copy of the given server proxy having the client method 1310 * constraints that result after the specified method mapping is 1311 * applied to the given client method constraints. 1312 */ 1313 private static Fiddler constrainServer( Fiddler server, 1314 MethodConstraints constraints ) 1315 { 1316 MethodConstraints newConstraints 1317 = ConstrainableProxyUtil.translateConstraints(constraints, 1318 methodMapArray); 1319 RemoteMethodControl constrainedServer = 1320 ((RemoteMethodControl)server).setConstraints(newConstraints); 1321 1322 return ((Fiddler)constrainedServer); 1323 }//end constrainServer 1324 1325 /** Returns a new copy of this proxy class 1326 * (<code>ConstrainableFiddlerRegistration</code>) with its client 1327 * constraints set to the specified constraints. A <code>null</code> 1328 * value is interpreted as mapping all methods to empty constraints. 1329 */ 1330 public RemoteMethodControl setConstraints 1331 (MethodConstraints constraints) 1332 { 1333 return (new ConstrainableFiddlerRegistration(server, 1334 registrationID, 1335 eventReg, 1336 constraints) ); 1337 }//end setConstraints 1338 1339 /** Returns the client constraints placed on the current instance of 1340 * this proxy class (<code>ConstrainableFiddlerRegistration</code>). 1341 * The value returned by this method can be <code>null</code>, 1342 * which is interpreted as mapping all methods to empty constraints. 1343 */ 1344 public MethodConstraints getConstraints() { 1345 return methodConstraints; 1346 }//end getConstraints 1347 1348 /** 1349 * Returns a proxy trust iterator that is used in 1350 * <code>ProxyTrustVerifier</code> to retrieve this object's 1351 * trust verifier. 1352 */ 1353 private ProxyTrustIterator getProxyTrustIterator() { 1354 return new SingletonProxyTrustIterator(server); 1355 }//end getProxyTrustIterator 1356 1357 /** Performs various functions related to the trust verification 1358 * process for the current instance of this proxy class, as 1359 * detailed in the description for this class. 1360 * 1361 * @throws <code>InvalidObjectException</code> if any of the 1362 * requirements for trust verification (as detailed in the 1363 * class description) are not satisfied. 1364 */ 1365 private void readObject(ObjectInputStream s) 1366 throws IOException, ClassNotFoundException 1367 { 1368 /* Note that basic validation of the fields of this class was 1369 * already performed in the readObject() method of this class' 1370 * super class. 1371 */ 1372 s.defaultReadObject(); 1373 /* Verify server1 constraints */ 1374 ConstrainableProxyUtil.verifyConsistentConstraints 1375 (methodConstraints, 1376 server, 1377 methodMapArray); 1378 1379 /* Verify server3 constraints */ 1380 Object source = eventReg.getSource(); 1381 if( !(source instanceof FiddlerProxy.ConstrainableFiddlerProxy) ) { 1382 throw new InvalidObjectException 1383 ("ConstrainableFiddlerRegistration.readObject " 1384 +"failure - eventReg source is not an instance " 1385 +" of ConstrainableFiddlerProxy"); 1386 }//endif 1387 /* Verify server4 constraints */ 1388 Object lease = eventReg.getLease(); 1389 if( !(lease instanceof FiddlerLease.ConstrainableFiddlerLease) ) { 1390 throw new InvalidObjectException 1391 ("ConstrainableFiddlerRegistration.readObject " 1392 +"failure - eventReg lease is not an instance " 1393 +" of ConstrainableFiddlerLease"); 1394 }//endif 1395 }//end readObject 1396 1397 }//end class ConstrainableFiddlerRegistration 1398 1399 }//end class FiddlerRegistration