/src/com/sun/corba/se/impl/transport/CorbaContactInfoListIteratorImpl.java
https://gitlab.com/borneywpf/openjdk-7-src · Java · 259 lines · 147 code · 37 blank · 75 comment · 18 complexity · 30927e451d28b8b1bf37485f1c6aef4c MD5 · raw file
- /*
- * Copyright (c) 2002, 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
- 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.