CorbaContactInfoListIteratorImpl.java revision 608:7e06bf1dcb09
1/* 2 * Copyright (c) 2002, 2004, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package com.sun.corba.se.impl.transport; 27 28import java.util.Iterator; 29import java.util.List; 30 31import org.omg.CORBA.COMM_FAILURE; 32import org.omg.CORBA.CompletionStatus; 33import org.omg.CORBA.INTERNAL; 34import org.omg.CORBA.SystemException; 35 36import com.sun.corba.se.pept.transport.ContactInfo ; 37import com.sun.corba.se.pept.transport.ContactInfoList ; 38 39import com.sun.corba.se.spi.ior.IOR ; 40import com.sun.corba.se.spi.logging.CORBALogDomains; 41import com.sun.corba.se.spi.orb.ORB ; 42import com.sun.corba.se.spi.transport.CorbaContactInfo; 43import com.sun.corba.se.spi.transport.CorbaContactInfoList; 44import com.sun.corba.se.spi.transport.CorbaContactInfoListIterator; 45import com.sun.corba.se.spi.transport.IIOPPrimaryToContactInfo; 46 47import com.sun.corba.se.impl.logging.ORBUtilSystemException; 48import com.sun.corba.se.impl.protocol.CorbaInvocationInfo; 49 50// REVISIT: create a unit test for this class. 51 52public class CorbaContactInfoListIteratorImpl 53 implements 54 CorbaContactInfoListIterator 55{ 56 protected ORB orb; 57 protected CorbaContactInfoList contactInfoList; 58 protected CorbaContactInfo successContactInfo; 59 protected CorbaContactInfo failureContactInfo; 60 protected RuntimeException failureException; 61 62 // ITERATOR state 63 protected Iterator effectiveTargetIORIterator; 64 protected CorbaContactInfo previousContactInfo; 65 protected boolean isAddrDispositionRetry; 66 protected IIOPPrimaryToContactInfo primaryToContactInfo; 67 protected ContactInfo primaryContactInfo; 68 protected List listOfContactInfos; 69 // End ITERATOR state 70 71 public CorbaContactInfoListIteratorImpl( 72 ORB orb, 73 CorbaContactInfoList corbaContactInfoList, 74 ContactInfo primaryContactInfo, 75 List listOfContactInfos) 76 { 77 this.orb = orb; 78 this.contactInfoList = corbaContactInfoList; 79 this.primaryContactInfo = primaryContactInfo; 80 if (listOfContactInfos != null) { 81 // listOfContactInfos is null when used by the legacy 82 // socket factory. In that case this iterator is NOT used. 83 this.effectiveTargetIORIterator = listOfContactInfos.iterator(); 84 } 85 // List is immutable so no need to synchronize access. 86 this.listOfContactInfos = listOfContactInfos; 87 88 this.previousContactInfo = null; 89 this.isAddrDispositionRetry = false; 90 91 this.successContactInfo = null; 92 this.failureContactInfo = null; 93 this.failureException = null; 94 95 primaryToContactInfo = orb.getORBData().getIIOPPrimaryToContactInfo(); 96 } 97 98 //////////////////////////////////////////////////// 99 // 100 // java.util.Iterator 101 // 102 103 public boolean hasNext() 104 { 105 // REVISIT: Implement as internal closure iterator which would 106 // wraps sticky or default. Then hasNext and next just call 107 // the closure. 108 109 if (isAddrDispositionRetry) { 110 return true; 111 } 112 113 boolean result; 114 115 if (primaryToContactInfo != null) { 116 result = primaryToContactInfo.hasNext(primaryContactInfo, 117 previousContactInfo, 118 listOfContactInfos); 119 } else { 120 result = effectiveTargetIORIterator.hasNext(); 121 } 122 123 return result; 124 } 125 126 public Object next() 127 { 128 if (isAddrDispositionRetry) { 129 isAddrDispositionRetry = false; 130 return previousContactInfo; 131 } 132 133 // We hold onto the last in case we get an addressing 134 // disposition retry. Then we use it again. 135 136 // We also hold onto it for the sticky manager. 137 138 if (primaryToContactInfo != null) { 139 previousContactInfo = (CorbaContactInfo) 140 primaryToContactInfo.next(primaryContactInfo, 141 previousContactInfo, 142 listOfContactInfos); 143 } else { 144 previousContactInfo = (CorbaContactInfo) 145 effectiveTargetIORIterator.next(); 146 } 147 148 return previousContactInfo; 149 } 150 151 public void remove() 152 { 153 throw new UnsupportedOperationException(); 154 } 155 156 //////////////////////////////////////////////////// 157 // 158 // com.sun.corba.se.pept.transport.ContactInfoListIterator 159 // 160 161 public ContactInfoList getContactInfoList() 162 { 163 return contactInfoList; 164 } 165 166 public void reportSuccess(ContactInfo contactInfo) 167 { 168 this.successContactInfo = (CorbaContactInfo)contactInfo; 169 } 170 171 public boolean reportException(ContactInfo contactInfo, 172 RuntimeException ex) 173 { 174 this.failureContactInfo = (CorbaContactInfo)contactInfo; 175 this.failureException = ex; 176 if (ex instanceof COMM_FAILURE) { 177 SystemException se = (SystemException) ex; 178 if (se.completed == CompletionStatus.COMPLETED_NO) { 179 if (hasNext()) { 180 return true; 181 } 182 if (contactInfoList.getEffectiveTargetIOR() != 183 contactInfoList.getTargetIOR()) 184 { 185 // retry from root ior 186 updateEffectiveTargetIOR(contactInfoList.getTargetIOR()); 187 return true; 188 } 189 } 190 } 191 return false; 192 } 193 194 public RuntimeException getFailureException() 195 { 196 if (failureException == null) { 197 return 198 ORBUtilSystemException.get( orb, 199 CORBALogDomains.RPC_TRANSPORT ) 200 .invalidContactInfoListIteratorFailureException(); 201 } else { 202 return failureException; 203 } 204 } 205 206 //////////////////////////////////////////////////// 207 // 208 // spi.CorbaContactInfoListIterator 209 // 210 211 public void reportAddrDispositionRetry(CorbaContactInfo contactInfo, 212 short disposition) 213 { 214 previousContactInfo.setAddressingDisposition(disposition); 215 isAddrDispositionRetry = true; 216 } 217 218 public void reportRedirect(CorbaContactInfo contactInfo, 219 IOR forwardedIOR) 220 { 221 updateEffectiveTargetIOR(forwardedIOR); 222 } 223 224 //////////////////////////////////////////////////// 225 // 226 // Implementation. 227 // 228 229 // 230 // REVISIT: 231 // 232 // The normal operation for a standard iterator is to throw 233 // ConcurrentModificationException whenever the underlying collection 234 // changes. This is implemented by keeping a modification counter (the 235 // timestamp may fail because the granularity is too coarse). 236 // Essentially what you need to do is whenever the iterator fails this 237 // way, go back to ContactInfoList and get a new iterator. 238 // 239 // Need to update CorbaClientRequestDispatchImpl to catch and use 240 // that exception. 241 // 242 243 public void updateEffectiveTargetIOR(IOR newIOR) 244 { 245 contactInfoList.setEffectiveTargetIOR(newIOR); 246 // If we report the exception in _request (i.e., beginRequest 247 // we cannot throw RemarshalException to the stub because _request 248 // does not declare that exception. 249 // To keep the two-level dispatching (first level chooses ContactInfo, 250 // second level is specific to that ContactInfo/EPT) we need to 251 // ensure that the request dispatchers get their iterator from the 252 // InvocationStack (i.e., ThreadLocal). That way if the list iterator 253 // needs a complete update it happens right here. 254 ((CorbaInvocationInfo)orb.getInvocationInfo()) 255 .setContactInfoListIterator(contactInfoList.iterator()); 256 } 257} 258 259// End of file. 260