1. /*
  2. * @(#)StubIORImpl.java 1.3 04/07/27
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. /*
  8. * Licensed Materials - Property of IBM
  9. * RMI-IIOP v1.0
  10. * Copyright IBM Corp. 1998 1999 All Rights Reserved
  11. *
  12. * US Government Users Restricted Rights - Use, duplication or
  13. * disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  14. */
  15. package com.sun.corba.se.impl.ior;
  16. import java.io.ObjectInputStream ;
  17. import java.io.ObjectOutputStream ;
  18. import java.io.IOException ;
  19. import java.io.StringWriter ;
  20. import org.omg.CORBA.ORB ;
  21. import org.omg.CORBA.portable.Delegate ;
  22. import org.omg.CORBA.portable.InputStream ;
  23. import org.omg.CORBA.portable.OutputStream ;
  24. // Be very careful: com.sun.corba imports must not depend on
  25. // PEORB internal classes in ways that prevent portability to
  26. // other vendor's ORBs.
  27. import com.sun.corba.se.spi.presentation.rmi.StubAdapter ;
  28. import com.sun.corba.se.impl.orbutil.HexOutputStream ;
  29. /**
  30. * This class implements a very simply IOR representation
  31. * which must be completely ORBImpl free so that this class
  32. * can be used in the implementation of a portable StubDelegateImpl.
  33. */
  34. public class StubIORImpl
  35. {
  36. // cached hash code
  37. private int hashCode;
  38. // IOR components
  39. private byte[] typeData;
  40. private int[] profileTags;
  41. private byte[][] profileData;
  42. public StubIORImpl()
  43. {
  44. hashCode = 0 ;
  45. typeData = null ;
  46. profileTags = null ;
  47. profileData = null ;
  48. }
  49. public String getRepositoryId()
  50. {
  51. if (typeData == null)
  52. return null ;
  53. return new String( typeData ) ;
  54. }
  55. public StubIORImpl( org.omg.CORBA.Object obj )
  56. {
  57. // write the IOR to an OutputStream and get an InputStream
  58. OutputStream ostr = StubAdapter.getORB( obj ).create_output_stream();
  59. ostr.write_Object(obj);
  60. InputStream istr = ostr.create_input_stream();
  61. // read the IOR components back from the stream
  62. int typeLength = istr.read_long();
  63. typeData = new byte[typeLength];
  64. istr.read_octet_array(typeData, 0, typeLength);
  65. int numProfiles = istr.read_long();
  66. profileTags = new int[numProfiles];
  67. profileData = new byte[numProfiles][];
  68. for (int i = 0; i < numProfiles; i++) {
  69. profileTags[i] = istr.read_long();
  70. profileData[i] = new byte[istr.read_long()];
  71. istr.read_octet_array(profileData[i], 0, profileData[i].length);
  72. }
  73. }
  74. public Delegate getDelegate( ORB orb )
  75. {
  76. // write the IOR components to an org.omg.CORBA.portable.OutputStream
  77. OutputStream ostr = orb.create_output_stream();
  78. ostr.write_long(typeData.length);
  79. ostr.write_octet_array(typeData, 0, typeData.length);
  80. ostr.write_long(profileTags.length);
  81. for (int i = 0; i < profileTags.length; i++) {
  82. ostr.write_long(profileTags[i]);
  83. ostr.write_long(profileData[i].length);
  84. ostr.write_octet_array(profileData[i], 0, profileData[i].length);
  85. }
  86. InputStream istr = ostr.create_input_stream() ;
  87. // read the IOR back from the stream
  88. org.omg.CORBA.Object obj = (org.omg.CORBA.Object)istr.read_Object();
  89. return StubAdapter.getDelegate( obj ) ;
  90. }
  91. public void doRead( java.io.ObjectInputStream stream )
  92. throws IOException, ClassNotFoundException
  93. {
  94. // read the IOR from the ObjectInputStream
  95. int typeLength = stream.readInt();
  96. typeData = new byte[typeLength];
  97. stream.readFully(typeData);
  98. int numProfiles = stream.readInt();
  99. profileTags = new int[numProfiles];
  100. profileData = new byte[numProfiles][];
  101. for (int i = 0; i < numProfiles; i++) {
  102. profileTags[i] = stream.readInt();
  103. profileData[i] = new byte[stream.readInt()];
  104. stream.readFully(profileData[i]);
  105. }
  106. }
  107. public void doWrite( ObjectOutputStream stream )
  108. throws IOException
  109. {
  110. // write the IOR to the ObjectOutputStream
  111. stream.writeInt(typeData.length);
  112. stream.write(typeData);
  113. stream.writeInt(profileTags.length);
  114. for (int i = 0; i < profileTags.length; i++) {
  115. stream.writeInt(profileTags[i]);
  116. stream.writeInt(profileData[i].length);
  117. stream.write(profileData[i]);
  118. }
  119. }
  120. /**
  121. * Returns a hash code value for the object which is the same for all stubs
  122. * that represent the same remote object.
  123. * @return the hash code value.
  124. */
  125. public synchronized int hashCode()
  126. {
  127. if (hashCode == 0) {
  128. // compute the hash code
  129. for (int i = 0; i < typeData.length; i++) {
  130. hashCode = hashCode * 37 + typeData[i];
  131. }
  132. for (int i = 0; i < profileTags.length; i++) {
  133. hashCode = hashCode * 37 + profileTags[i];
  134. for (int j = 0; j < profileData[i].length; j++) {
  135. hashCode = hashCode * 37 + profileData[i][j];
  136. }
  137. }
  138. }
  139. return hashCode;
  140. }
  141. private boolean equalArrays( int[] data1, int[] data2 )
  142. {
  143. if (data1.length != data2.length)
  144. return false ;
  145. for (int ctr=0; ctr<data1.length; ctr++) {
  146. if (data1[ctr] != data2[ctr])
  147. return false ;
  148. }
  149. return true ;
  150. }
  151. private boolean equalArrays( byte[] data1, byte[] data2 )
  152. {
  153. if (data1.length != data2.length)
  154. return false ;
  155. for (int ctr=0; ctr<data1.length; ctr++) {
  156. if (data1[ctr] != data2[ctr])
  157. return false ;
  158. }
  159. return true ;
  160. }
  161. private boolean equalArrays( byte[][] data1, byte[][] data2 )
  162. {
  163. if (data1.length != data2.length)
  164. return false ;
  165. for (int ctr=0; ctr<data1.length; ctr++) {
  166. if (!equalArrays( data1[ctr], data2[ctr] ))
  167. return false ;
  168. }
  169. return true ;
  170. }
  171. public boolean equals(java.lang.Object obj)
  172. {
  173. if (this == obj) {
  174. return true;
  175. }
  176. if (!(obj instanceof StubIORImpl)) {
  177. return false;
  178. }
  179. StubIORImpl other = (StubIORImpl) obj;
  180. if (other.hashCode() != this.hashCode()) {
  181. return false;
  182. }
  183. return equalArrays( typeData, other.typeData ) &&
  184. equalArrays( profileTags, other.profileTags ) &&
  185. equalArrays( profileData, other.profileData ) ;
  186. }
  187. private void appendByteArray( StringBuffer result, byte[] data )
  188. {
  189. for ( int ctr=0; ctr<data.length; ctr++ ) {
  190. result.append( Integer.toHexString( data[ctr] ) ) ;
  191. }
  192. }
  193. /**
  194. * Returns a string representation of this stub. Returns the same string
  195. * for all stubs that represent the same remote object.
  196. * "SimpleIORImpl[<typeName>,[<profileID>]data, ...]"
  197. * @return a string representation of this stub.
  198. */
  199. public String toString()
  200. {
  201. StringBuffer result = new StringBuffer() ;
  202. result.append( "SimpleIORImpl[" ) ;
  203. String repositoryId = new String( typeData ) ;
  204. result.append( repositoryId ) ;
  205. for (int ctr=0; ctr<profileTags.length; ctr++) {
  206. result.append( ",(" ) ;
  207. result.append( profileTags[ctr] ) ;
  208. result.append( ")" ) ;
  209. appendByteArray( result, profileData[ctr] ) ;
  210. }
  211. result.append( "]" ) ;
  212. return result.toString() ;
  213. }
  214. }