1. /*
  2. * @(#)IORImpl.java 1.30 03/12/19
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package com.sun.corba.se.impl.ior;
  8. import java.util.ListIterator ;
  9. import java.util.Iterator ;
  10. import java.util.Map ;
  11. import java.util.HashMap ;
  12. import java.io.StringWriter;
  13. import java.io.IOException;
  14. import javax.rmi.CORBA.Util;
  15. import org.omg.CORBA_2_3.portable.InputStream ;
  16. import org.omg.CORBA_2_3.portable.OutputStream ;
  17. import org.omg.IOP.TAG_INTERNET_IOP ;
  18. import com.sun.corba.se.spi.ior.ObjectId ;
  19. import com.sun.corba.se.spi.ior.TaggedProfileTemplate ;
  20. import com.sun.corba.se.spi.ior.TaggedProfile ;
  21. import com.sun.corba.se.spi.ior.IOR ;
  22. import com.sun.corba.se.spi.ior.IORTemplate ;
  23. import com.sun.corba.se.spi.ior.IORTemplateList ;
  24. import com.sun.corba.se.spi.ior.IdentifiableFactoryFinder ;
  25. import com.sun.corba.se.spi.ior.IdentifiableContainerBase ;
  26. import com.sun.corba.se.spi.ior.ObjectKeyTemplate ;
  27. import com.sun.corba.se.spi.ior.IORFactories ;
  28. import com.sun.corba.se.spi.ior.iiop.GIOPVersion;
  29. import com.sun.corba.se.spi.protocol.RequestDispatcherRegistry;
  30. import com.sun.corba.se.spi.orb.ORB;
  31. import com.sun.corba.se.spi.logging.CORBALogDomains;
  32. import com.sun.corba.se.impl.encoding.MarshalOutputStream;
  33. import com.sun.corba.se.impl.encoding.EncapsOutputStream;
  34. import com.sun.corba.se.impl.orbutil.HexOutputStream;
  35. import com.sun.corba.se.impl.orbutil.ORBConstants;
  36. import com.sun.corba.se.impl.logging.IORSystemException ;
  37. // XXX remove this once getProfile is gone
  38. import com.sun.corba.se.spi.ior.iiop.IIOPProfile ;
  39. /** An IOR is represented as a list of profiles.
  40. * Only objects that extend TaggedProfile should be added to an IOR.
  41. * However, enforcing this restriction requires overriding all
  42. * of the addXXX methods inherited from List, so no check
  43. * is included here.
  44. * @author Ken Cavanaugh
  45. */
  46. public class IORImpl extends IdentifiableContainerBase implements IOR
  47. {
  48. private String typeId;
  49. private ORB factory = null ;
  50. IORSystemException wrapper ;
  51. public ORB getORB()
  52. {
  53. return factory ;
  54. }
  55. /* This variable is set directly from the constructors that take
  56. * an IORTemplate or IORTemplateList as arguments; otherwise it
  57. * is derived from the list of TaggedProfile instances on the first
  58. * call to getIORTemplates. Note that we assume that an IOR with
  59. * mutiple TaggedProfile instances has the same ObjectId in each
  60. * TaggedProfile, as otherwise the IOR could never be created through
  61. * an ObjectReferenceFactory.
  62. */
  63. private IORTemplateList iortemps = null ;
  64. public boolean equals( Object obj )
  65. {
  66. if (obj == null)
  67. return false ;
  68. if (!(obj instanceof IOR))
  69. return false ;
  70. IOR other = (IOR)obj ;
  71. return super.equals( obj ) && typeId.equals( other.getTypeId() ) ;
  72. }
  73. public int hashCode()
  74. {
  75. return super.hashCode() ^ typeId.hashCode() ;
  76. }
  77. /** Construct an empty IOR. This is needed for null object references.
  78. */
  79. public IORImpl( ORB orb )
  80. {
  81. this( orb, "" ) ;
  82. }
  83. public IORImpl( ORB orb, String typeid )
  84. {
  85. factory = orb ;
  86. wrapper = IORSystemException.get( orb,
  87. CORBALogDomains.OA_IOR ) ;
  88. this.typeId = typeid ;
  89. }
  90. /** Construct an IOR from an IORTemplate by applying the same
  91. * object id to each TaggedProfileTemplate in the IORTemplate.
  92. */
  93. public IORImpl( ORB orb, String typeId, IORTemplate iortemp, ObjectId id)
  94. {
  95. this( orb, typeId ) ;
  96. this.iortemps = IORFactories.makeIORTemplateList() ;
  97. this.iortemps.add( iortemp ) ;
  98. addTaggedProfiles( iortemp, id ) ;
  99. makeImmutable() ;
  100. }
  101. private void addTaggedProfiles( IORTemplate iortemp, ObjectId id )
  102. {
  103. ObjectKeyTemplate oktemp = iortemp.getObjectKeyTemplate() ;
  104. Iterator templateIterator = iortemp.iterator() ;
  105. while (templateIterator.hasNext()) {
  106. TaggedProfileTemplate ptemp =
  107. (TaggedProfileTemplate)(templateIterator.next()) ;
  108. TaggedProfile profile = ptemp.create( oktemp, id ) ;
  109. add( profile ) ;
  110. }
  111. }
  112. /** Construct an IOR from an IORTemplate by applying the same
  113. * object id to each TaggedProfileTemplate in the IORTemplate.
  114. */
  115. public IORImpl( ORB orb, String typeId, IORTemplateList iortemps, ObjectId id)
  116. {
  117. this( orb, typeId ) ;
  118. this.iortemps = iortemps ;
  119. Iterator iter = iortemps.iterator() ;
  120. while (iter.hasNext()) {
  121. IORTemplate iortemp = (IORTemplate)(iter.next()) ;
  122. addTaggedProfiles( iortemp, id ) ;
  123. }
  124. makeImmutable() ;
  125. }
  126. public IORImpl(InputStream is)
  127. {
  128. this( (ORB)(is.orb()), is.read_string() ) ;
  129. IdentifiableFactoryFinder finder =
  130. factory.getTaggedProfileFactoryFinder() ;
  131. EncapsulationUtility.readIdentifiableSequence( this, finder, is ) ;
  132. makeImmutable() ;
  133. }
  134. public String getTypeId()
  135. {
  136. return typeId ;
  137. }
  138. public void write(OutputStream os)
  139. {
  140. os.write_string( typeId ) ;
  141. EncapsulationUtility.writeIdentifiableSequence( this, os ) ;
  142. }
  143. public String stringify()
  144. {
  145. StringWriter bs;
  146. MarshalOutputStream s = new EncapsOutputStream(factory);
  147. s.putEndian();
  148. write( (OutputStream)s );
  149. bs = new StringWriter();
  150. try {
  151. s.writeTo(new HexOutputStream(bs));
  152. } catch (IOException ex) {
  153. throw wrapper.stringifyWriteError( ex ) ;
  154. }
  155. return ORBConstants.STRINGIFY_PREFIX + bs;
  156. }
  157. public synchronized void makeImmutable()
  158. {
  159. makeElementsImmutable() ;
  160. if (iortemps != null)
  161. iortemps.makeImmutable() ;
  162. super.makeImmutable() ;
  163. }
  164. public org.omg.IOP.IOR getIOPIOR() {
  165. EncapsOutputStream os = new EncapsOutputStream(factory);
  166. write(os);
  167. InputStream is = (InputStream) (os.create_input_stream());
  168. return org.omg.IOP.IORHelper.read(is);
  169. }
  170. public boolean isNil()
  171. {
  172. //
  173. // The check for typeId length of 0 below is commented out
  174. // as a workaround for a bug in ORBs which send a
  175. // null objref with a non-empty typeId string.
  176. //
  177. return ((size() == 0) /* && (typeId.length() == 0) */);
  178. }
  179. public boolean isEquivalent(IOR ior)
  180. {
  181. Iterator myIterator = iterator() ;
  182. Iterator otherIterator = ior.iterator() ;
  183. while (myIterator.hasNext() && otherIterator.hasNext()) {
  184. TaggedProfile myProfile = (TaggedProfile)(myIterator.next()) ;
  185. TaggedProfile otherProfile = (TaggedProfile)(otherIterator.next()) ;
  186. if (!myProfile.isEquivalent( otherProfile ))
  187. return false ;
  188. }
  189. return myIterator.hasNext() == otherIterator.hasNext() ;
  190. }
  191. private void initializeIORTemplateList()
  192. {
  193. // Maps ObjectKeyTemplate to IORTemplate
  194. Map oktempToIORTemplate = new HashMap() ;
  195. iortemps = IORFactories.makeIORTemplateList() ;
  196. Iterator iter = iterator() ;
  197. ObjectId oid = null ; // used to check that all profiles have the same oid.
  198. while (iter.hasNext()) {
  199. TaggedProfile prof = (TaggedProfile)(iter.next()) ;
  200. TaggedProfileTemplate ptemp = prof.getTaggedProfileTemplate() ;
  201. ObjectKeyTemplate oktemp = prof.getObjectKeyTemplate() ;
  202. // Check that all oids for all profiles are the same: if they are not,
  203. // throw exception.
  204. if (oid == null)
  205. oid = prof.getObjectId() ;
  206. else if (!oid.equals( prof.getObjectId() ))
  207. throw wrapper.badOidInIorTemplateList() ;
  208. // Find or create the IORTemplate for oktemp.
  209. IORTemplate iortemp = (IORTemplate)(oktempToIORTemplate.get( oktemp )) ;
  210. if (iortemp == null) {
  211. iortemp = IORFactories.makeIORTemplate( oktemp ) ;
  212. oktempToIORTemplate.put( oktemp, iortemp ) ;
  213. iortemps.add( iortemp ) ;
  214. }
  215. iortemp.add( ptemp ) ;
  216. }
  217. iortemps.makeImmutable() ;
  218. }
  219. /** Return the IORTemplateList for this IOR. Will throw
  220. * exception if it is not possible to generate an IOR
  221. * from the IORTemplateList that is equal to this IOR,
  222. * which can only happen if not every TaggedProfile in the
  223. * IOR has the same ObjectId.
  224. */
  225. public synchronized IORTemplateList getIORTemplates()
  226. {
  227. if (iortemps == null)
  228. initializeIORTemplateList() ;
  229. return iortemps ;
  230. }
  231. /** Return the first IIOPProfile in this IOR.
  232. * XXX THIS IS TEMPORARY FOR BACKWARDS COMPATIBILITY AND WILL BE REMOVED
  233. * SOON!
  234. */
  235. public IIOPProfile getProfile()
  236. {
  237. IIOPProfile iop = null ;
  238. Iterator iter = iteratorById( TAG_INTERNET_IOP.value ) ;
  239. if (iter.hasNext())
  240. iop = (IIOPProfile)(iter.next()) ;
  241. if (iop != null)
  242. return iop ;
  243. // if we come to this point then no IIOP Profile
  244. // is present. Therefore, throw an exception.
  245. throw wrapper.iorMustHaveIiopProfile() ;
  246. }
  247. }