IORImpl.java revision 608:7e06bf1dcb09
1/* 2 * Copyright (c) 2000, 2013, 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.ior; 27 28import java.util.ListIterator ; 29import java.util.Iterator ; 30import java.util.Map ; 31import java.util.HashMap ; 32 33import java.io.StringWriter; 34import java.io.IOException; 35 36import javax.rmi.CORBA.Util; 37 38import org.omg.CORBA_2_3.portable.InputStream ; 39import org.omg.CORBA_2_3.portable.OutputStream ; 40 41import org.omg.IOP.TAG_INTERNET_IOP ; 42 43import com.sun.corba.se.spi.ior.ObjectId ; 44import com.sun.corba.se.spi.ior.TaggedProfileTemplate ; 45import com.sun.corba.se.spi.ior.TaggedProfile ; 46import com.sun.corba.se.spi.ior.IOR ; 47import com.sun.corba.se.spi.ior.IORTemplate ; 48import com.sun.corba.se.spi.ior.IORTemplateList ; 49import com.sun.corba.se.spi.ior.IdentifiableFactoryFinder ; 50import com.sun.corba.se.spi.ior.IdentifiableContainerBase ; 51import com.sun.corba.se.spi.ior.ObjectKeyTemplate ; 52import com.sun.corba.se.spi.ior.IORFactories ; 53 54import com.sun.corba.se.spi.ior.iiop.GIOPVersion; 55 56import com.sun.corba.se.spi.protocol.RequestDispatcherRegistry; 57 58import com.sun.corba.se.spi.orb.ORB; 59 60import com.sun.corba.se.spi.logging.CORBALogDomains; 61 62import com.sun.corba.se.impl.encoding.MarshalOutputStream; 63 64import com.sun.corba.se.impl.encoding.EncapsOutputStream; 65 66import com.sun.corba.se.impl.orbutil.HexOutputStream; 67import com.sun.corba.se.impl.orbutil.ORBConstants; 68 69import com.sun.corba.se.impl.logging.IORSystemException ; 70 71// XXX remove this once getProfile is gone 72import com.sun.corba.se.spi.ior.iiop.IIOPProfile ; 73 74/** An IOR is represented as a list of profiles. 75* Only objects that extend TaggedProfile should be added to an IOR. 76* However, enforcing this restriction requires overriding all 77* of the addXXX methods inherited from List, so no check 78* is included here. 79* @author Ken Cavanaugh 80*/ 81public class IORImpl extends IdentifiableContainerBase implements IOR 82{ 83 private String typeId; 84 private ORB factory = null ; 85 private boolean isCachedHashValue = false; 86 private int cachedHashValue; 87 IORSystemException wrapper ; 88 89 public ORB getORB() 90 { 91 return factory ; 92 } 93 94 /* This variable is set directly from the constructors that take 95 * an IORTemplate or IORTemplateList as arguments; otherwise it 96 * is derived from the list of TaggedProfile instances on the first 97 * call to getIORTemplates. Note that we assume that an IOR with 98 * mutiple TaggedProfile instances has the same ObjectId in each 99 * TaggedProfile, as otherwise the IOR could never be created through 100 * an ObjectReferenceFactory. 101 */ 102 private IORTemplateList iortemps = null ; 103 104 public boolean equals( Object obj ) 105 { 106 if (obj == null) 107 return false ; 108 109 if (!(obj instanceof IOR)) 110 return false ; 111 112 IOR other = (IOR)obj ; 113 114 return super.equals( obj ) && typeId.equals( other.getTypeId() ) ; 115 } 116 117 public synchronized int hashCode() 118 { 119 if (! isCachedHashValue) { 120 cachedHashValue = (super.hashCode() ^ typeId.hashCode()); 121 isCachedHashValue = true; 122 } 123 return cachedHashValue; 124 } 125 126 /** Construct an empty IOR. This is needed for null object references. 127 */ 128 public IORImpl( ORB orb ) 129 { 130 this( orb, "" ) ; 131 } 132 133 public IORImpl( ORB orb, String typeid ) 134 { 135 factory = orb ; 136 wrapper = IORSystemException.get( orb, 137 CORBALogDomains.OA_IOR ) ; 138 this.typeId = typeid ; 139 } 140 141 /** Construct an IOR from an IORTemplate by applying the same 142 * object id to each TaggedProfileTemplate in the IORTemplate. 143 */ 144 public IORImpl( ORB orb, String typeId, IORTemplate iortemp, ObjectId id) 145 { 146 this( orb, typeId ) ; 147 148 this.iortemps = IORFactories.makeIORTemplateList() ; 149 this.iortemps.add( iortemp ) ; 150 151 addTaggedProfiles( iortemp, id ) ; 152 153 makeImmutable() ; 154 } 155 156 private void addTaggedProfiles( IORTemplate iortemp, ObjectId id ) 157 { 158 ObjectKeyTemplate oktemp = iortemp.getObjectKeyTemplate() ; 159 Iterator templateIterator = iortemp.iterator() ; 160 161 while (templateIterator.hasNext()) { 162 TaggedProfileTemplate ptemp = 163 (TaggedProfileTemplate)(templateIterator.next()) ; 164 165 TaggedProfile profile = ptemp.create( oktemp, id ) ; 166 167 add( profile ) ; 168 } 169 } 170 171 /** Construct an IOR from an IORTemplate by applying the same 172 * object id to each TaggedProfileTemplate in the IORTemplate. 173 */ 174 public IORImpl( ORB orb, String typeId, IORTemplateList iortemps, ObjectId id) 175 { 176 this( orb, typeId ) ; 177 178 this.iortemps = iortemps ; 179 180 Iterator iter = iortemps.iterator() ; 181 while (iter.hasNext()) { 182 IORTemplate iortemp = (IORTemplate)(iter.next()) ; 183 addTaggedProfiles( iortemp, id ) ; 184 } 185 186 makeImmutable() ; 187 } 188 189 public IORImpl(InputStream is) 190 { 191 this( (ORB)(is.orb()), is.read_string() ) ; 192 193 IdentifiableFactoryFinder finder = 194 factory.getTaggedProfileFactoryFinder() ; 195 196 EncapsulationUtility.readIdentifiableSequence( this, finder, is ) ; 197 198 makeImmutable() ; 199 } 200 201 public String getTypeId() 202 { 203 return typeId ; 204 } 205 206 public void write(OutputStream os) 207 { 208 os.write_string( typeId ) ; 209 EncapsulationUtility.writeIdentifiableSequence( this, os ) ; 210 } 211 212 public String stringify() 213 { 214 StringWriter bs; 215 216 MarshalOutputStream s = 217 sun.corba.OutputStreamFactory.newEncapsOutputStream(factory); 218 s.putEndian(); 219 write( (OutputStream)s ); 220 bs = new StringWriter(); 221 try { 222 s.writeTo(new HexOutputStream(bs)); 223 } catch (IOException ex) { 224 throw wrapper.stringifyWriteError( ex ) ; 225 } 226 227 return ORBConstants.STRINGIFY_PREFIX + bs; 228 } 229 230 public synchronized void makeImmutable() 231 { 232 makeElementsImmutable() ; 233 234 if (iortemps != null) 235 iortemps.makeImmutable() ; 236 237 super.makeImmutable() ; 238 } 239 240 public org.omg.IOP.IOR getIOPIOR() { 241 EncapsOutputStream os = 242 sun.corba.OutputStreamFactory.newEncapsOutputStream(factory); 243 write(os); 244 InputStream is = (InputStream) (os.create_input_stream()); 245 return org.omg.IOP.IORHelper.read(is); 246 } 247 248 public boolean isNil() 249 { 250 // 251 // The check for typeId length of 0 below is commented out 252 // as a workaround for a bug in ORBs which send a 253 // null objref with a non-empty typeId string. 254 // 255 return ((size() == 0) /* && (typeId.length() == 0) */); 256 } 257 258 public boolean isEquivalent(IOR ior) 259 { 260 Iterator myIterator = iterator() ; 261 Iterator otherIterator = ior.iterator() ; 262 while (myIterator.hasNext() && otherIterator.hasNext()) { 263 TaggedProfile myProfile = (TaggedProfile)(myIterator.next()) ; 264 TaggedProfile otherProfile = (TaggedProfile)(otherIterator.next()) ; 265 if (!myProfile.isEquivalent( otherProfile )) 266 return false ; 267 } 268 269 return myIterator.hasNext() == otherIterator.hasNext() ; 270 } 271 272 private void initializeIORTemplateList() 273 { 274 // Maps ObjectKeyTemplate to IORTemplate 275 Map oktempToIORTemplate = new HashMap() ; 276 277 iortemps = IORFactories.makeIORTemplateList() ; 278 Iterator iter = iterator() ; 279 ObjectId oid = null ; // used to check that all profiles have the same oid. 280 while (iter.hasNext()) { 281 TaggedProfile prof = (TaggedProfile)(iter.next()) ; 282 TaggedProfileTemplate ptemp = prof.getTaggedProfileTemplate() ; 283 ObjectKeyTemplate oktemp = prof.getObjectKeyTemplate() ; 284 285 // Check that all oids for all profiles are the same: if they are not, 286 // throw exception. 287 if (oid == null) 288 oid = prof.getObjectId() ; 289 else if (!oid.equals( prof.getObjectId() )) 290 throw wrapper.badOidInIorTemplateList() ; 291 292 // Find or create the IORTemplate for oktemp. 293 IORTemplate iortemp = (IORTemplate)(oktempToIORTemplate.get( oktemp )) ; 294 if (iortemp == null) { 295 iortemp = IORFactories.makeIORTemplate( oktemp ) ; 296 oktempToIORTemplate.put( oktemp, iortemp ) ; 297 iortemps.add( iortemp ) ; 298 } 299 300 iortemp.add( ptemp ) ; 301 } 302 303 iortemps.makeImmutable() ; 304 } 305 306 /** Return the IORTemplateList for this IOR. Will throw 307 * exception if it is not possible to generate an IOR 308 * from the IORTemplateList that is equal to this IOR, 309 * which can only happen if not every TaggedProfile in the 310 * IOR has the same ObjectId. 311 */ 312 public synchronized IORTemplateList getIORTemplates() 313 { 314 if (iortemps == null) 315 initializeIORTemplateList() ; 316 317 return iortemps ; 318 } 319 320 /** Return the first IIOPProfile in this IOR. 321 * XXX THIS IS TEMPORARY FOR BACKWARDS COMPATIBILITY AND WILL BE REMOVED 322 * SOON! 323 */ 324 public IIOPProfile getProfile() 325 { 326 IIOPProfile iop = null ; 327 Iterator iter = iteratorById( TAG_INTERNET_IOP.value ) ; 328 if (iter.hasNext()) 329 iop = (IIOPProfile)(iter.next()) ; 330 331 if (iop != null) 332 return iop ; 333 334 // if we come to this point then no IIOP Profile 335 // is present. Therefore, throw an exception. 336 throw wrapper.iorMustHaveIiopProfile() ; 337 } 338} 339