- /*
- * @(#)CorbaContactInfoListIteratorImpl.java 1.29 04/06/21
- *
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
- * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- */
-
- package com.sun.corba.se.impl.transport;
-
- import java.util.Iterator;
- import java.util.List;
-
- import org.omg.CORBA.COMM_FAILURE;
- import org.omg.CORBA.CompletionStatus;
- import org.omg.CORBA.INTERNAL;
- import org.omg.CORBA.SystemException;
-
- import com.sun.corba.se.pept.transport.ContactInfo ;
- import com.sun.corba.se.pept.transport.ContactInfoList ;
-
- import com.sun.corba.se.spi.ior.IOR ;
- import com.sun.corba.se.spi.logging.CORBALogDomains;
- import com.sun.corba.se.spi.orb.ORB ;
- import com.sun.corba.se.spi.transport.CorbaContactInfo;
- import com.sun.corba.se.spi.transport.CorbaContactInfoList;
- import com.sun.corba.se.spi.transport.CorbaContactInfoListIterator;
- import com.sun.corba.se.spi.transport.IIOPPrimaryToContactInfo;
-
- import com.sun.corba.se.impl.logging.ORBUtilSystemException;
- import com.sun.corba.se.impl.protocol.CorbaInvocationInfo;
-
- // REVISIT: create a unit test for this class.
-
- public class CorbaContactInfoListIteratorImpl
- implements
- CorbaContactInfoListIterator
- {
- protected ORB orb;
- protected CorbaContactInfoList contactInfoList;
- protected CorbaContactInfo successContactInfo;
- protected CorbaContactInfo failureContactInfo;
- protected RuntimeException failureException;
-
- // ITERATOR state
- protected Iterator effectiveTargetIORIterator;
- protected CorbaContactInfo previousContactInfo;
- protected boolean isAddrDispositionRetry;
- protected IIOPPrimaryToContactInfo primaryToContactInfo;
- protected ContactInfo primaryContactInfo;
- protected List listOfContactInfos;
- // End ITERATOR state
-
- public CorbaContactInfoListIteratorImpl(
- ORB orb,
- CorbaContactInfoList corbaContactInfoList,
- ContactInfo primaryContactInfo,
- List listOfContactInfos)
- {
- this.orb = orb;
- this.contactInfoList = corbaContactInfoList;
- this.primaryContactInfo = primaryContactInfo;
- if (listOfContactInfos != null) {
- // listOfContactInfos is null when used by the legacy
- // socket factory. In that case this iterator is NOT used.
- this.effectiveTargetIORIterator = listOfContactInfos.iterator();
- }
- // List is immutable so no need to synchronize access.
- this.listOfContactInfos = listOfContactInfos;
-
- this.previousContactInfo = null;
- this.isAddrDispositionRetry = false;
-
- this.successContactInfo = null;
- this.failureContactInfo = null;
- this.failureException = null;
-
- primaryToContactInfo = orb.getORBData().getIIOPPrimaryToContactInfo();
- }
-
- ////////////////////////////////////////////////////
- //
- // java.util.Iterator
- //
-
- public boolean hasNext()
- {
- // REVISIT: Implement as internal closure iterator which would
- // wraps sticky or default. Then hasNext and next just call
- // the closure.
-
- if (isAddrDispositionRetry) {
- return true;
- }
-
- boolean result;
-
- if (primaryToContactInfo != null) {
- result = primaryToContactInfo.hasNext(primaryContactInfo,
- previousContactInfo,
- listOfContactInfos);
- } else {
- result = effectiveTargetIORIterator.hasNext();
- }
-
- return result;
- }
-
- public Object next()
- {
- if (isAddrDispositionRetry) {
- isAddrDispositionRetry = false;
- return previousContactInfo;
- }
-
- // We hold onto the last in case we get an addressing
- // disposition retry. Then we use it again.
-
- // We also hold onto it for the sticky manager.
-
- if (primaryToContactInfo != null) {
- previousContactInfo = (CorbaContactInfo)
- primaryToContactInfo.next(primaryContactInfo,
- previousContactInfo,
- listOfContactInfos);
- } else {
- previousContactInfo = (CorbaContactInfo)
- effectiveTargetIORIterator.next();
- }
-
- return previousContactInfo;
- }
-
- public void remove()
- {
- throw new UnsupportedOperationException();
- }
-
- ////////////////////////////////////////////////////
- //
- // com.sun.corba.se.pept.transport.ContactInfoListIterator
- //
-
- public ContactInfoList getContactInfoList()
- {
- return contactInfoList;
- }
-
- public void reportSuccess(ContactInfo contactInfo)
- {
- this.successContactInfo = (CorbaContactInfo)contactInfo;
- }
-
- public boolean reportException(ContactInfo contactInfo,
- RuntimeException ex)
- {
- this.failureContactInfo = (CorbaContactInfo)contactInfo;
- this.failureException = ex;
- if (ex instanceof COMM_FAILURE) {
- SystemException se = (SystemException) ex;
- if (se.completed == CompletionStatus.COMPLETED_NO) {
- if (hasNext()) {
- return true;
- }
- if (contactInfoList.getEffectiveTargetIOR() !=
- contactInfoList.getTargetIOR())
- {
- // retry from root ior
- updateEffectiveTargetIOR(contactInfoList.getTargetIOR());
- return true;
- }
- }
- }
- return false;
- }
-
- public RuntimeException getFailureException()
- {
- if (failureException == null) {
- return
- ORBUtilSystemException.get( orb,
- CORBALogDomains.RPC_TRANSPORT )
- .invalidContactInfoListIteratorFailureException();
- } else {
- return failureException;
- }
- }
-
- ////////////////////////////////////////////////////
- //
- // spi.CorbaContactInfoListIterator
- //
-
- public void reportAddrDispositionRetry(CorbaContactInfo contactInfo,
- short disposition)
- {
- previousContactInfo.setAddressingDisposition(disposition);
- isAddrDispositionRetry = true;
- }
-
- public void reportRedirect(CorbaContactInfo contactInfo,
- IOR forwardedIOR)
- {
- updateEffectiveTargetIOR(forwardedIOR);
- }
-
- ////////////////////////////////////////////////////
- //
- // Implementation.
- //
-
- //
- // REVISIT:
- //
- // The normal operation for a standard iterator is to throw
- // ConcurrentModificationException whenever the underlying collection
- // changes. This is implemented by keeping a modification counter (the
- // timestamp may fail because the granularity is too coarse).
- // Essentially what you need to do is whenever the iterator fails this
- // way, go back to ContactInfoList and get a new iterator.
- //
- // Need to update CorbaClientRequestDispatchImpl to catch and use
- // that exception.
- //
-
- public void updateEffectiveTargetIOR(IOR newIOR)
- {
- contactInfoList.setEffectiveTargetIOR(newIOR);
- // If we report the exception in _request (i.e., beginRequest
- // we cannot throw RemarshalException to the stub because _request
- // does not declare that exception.
- // To keep the two-level dispatching (first level chooses ContactInfo,
- // second level is specific to that ContactInfo/EPT) we need to
- // ensure that the request dispatchers get their iterator from the
- // InvocationStack (i.e., ThreadLocal). That way if the list iterator
- // needs a complete update it happens right here.
- ((CorbaInvocationInfo)orb.getInvocationInfo())
- .setContactInfoListIterator(contactInfoList.iterator());
- }
- }
-
- // End of file.