Wed, 07 Feb 2018 00:10:57 -0800
8192757: Improve stub classes implementation
Reviewed-by: rriggs, dfuchs, erikj
1 /*
2 * Copyright (c) 2003, 2018, 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 /*
26 * Licensed Materials - Property of IBM
27 * RMI-IIOP v1.0
28 * Copyright IBM Corp. 1998 1999 All Rights Reserved
29 *
30 */
32 package com.sun.corba.se.impl.ior;
34 import java.io.ObjectInputStream ;
35 import java.io.ObjectOutputStream ;
36 import java.io.IOException ;
38 import org.omg.CORBA.ORB ;
40 import org.omg.CORBA.portable.Delegate ;
41 import org.omg.CORBA.portable.InputStream ;
42 import org.omg.CORBA.portable.OutputStream ;
44 // Be very careful: com.sun.corba imports must not depend on
45 // PEORB internal classes in ways that prevent portability to
46 // other vendor's ORBs.
47 import com.sun.corba.se.spi.presentation.rmi.StubAdapter ;
48 import com.sun.corba.se.impl.orbutil.HexOutputStream ;
49 import sun.corba.SharedSecrets;
51 /**
52 * This class implements a very simply IOR representation
53 * which must be completely ORBImpl free so that this class
54 * can be used in the implementation of a portable StubDelegateImpl.
55 */
56 public class StubIORImpl
57 {
58 // cached hash code
59 private int hashCode;
61 // IOR components
62 private byte[] typeData;
63 private int[] profileTags;
64 private byte[][] profileData;
66 public StubIORImpl()
67 {
68 hashCode = 0 ;
69 typeData = null ;
70 profileTags = null ;
71 profileData = null ;
72 }
74 public String getRepositoryId()
75 {
76 if (typeData == null)
77 return null ;
79 return new String( typeData ) ;
80 }
82 public StubIORImpl( org.omg.CORBA.Object obj )
83 {
84 // write the IOR to an OutputStream and get an InputStream
85 OutputStream ostr = StubAdapter.getORB( obj ).create_output_stream();
86 ostr.write_Object(obj);
87 InputStream istr = ostr.create_input_stream();
89 // read the IOR components back from the stream
90 int typeLength = istr.read_long();
91 typeData = new byte[typeLength];
92 istr.read_octet_array(typeData, 0, typeLength);
93 int numProfiles = istr.read_long();
94 profileTags = new int[numProfiles];
95 profileData = new byte[numProfiles][];
96 for (int i = 0; i < numProfiles; i++) {
97 profileTags[i] = istr.read_long();
98 profileData[i] = new byte[istr.read_long()];
99 istr.read_octet_array(profileData[i], 0, profileData[i].length);
100 }
101 }
103 public Delegate getDelegate( ORB orb )
104 {
105 // write the IOR components to an org.omg.CORBA.portable.OutputStream
106 OutputStream ostr = orb.create_output_stream();
107 ostr.write_long(typeData.length);
108 ostr.write_octet_array(typeData, 0, typeData.length);
109 ostr.write_long(profileTags.length);
110 for (int i = 0; i < profileTags.length; i++) {
111 ostr.write_long(profileTags[i]);
112 ostr.write_long(profileData[i].length);
113 ostr.write_octet_array(profileData[i], 0, profileData[i].length);
114 }
116 InputStream istr = ostr.create_input_stream() ;
118 // read the IOR back from the stream
119 org.omg.CORBA.Object obj = (org.omg.CORBA.Object)istr.read_Object();
120 return StubAdapter.getDelegate( obj ) ;
121 }
123 public void doRead( java.io.ObjectInputStream stream )
124 throws IOException, ClassNotFoundException
125 {
126 // read the IOR from the ObjectInputStream
127 int typeLength = stream.readInt();
128 SharedSecrets.getJavaOISAccess().checkArray(stream, byte[].class, typeLength);
129 typeData = new byte[typeLength];
130 stream.readFully(typeData);
132 int numProfiles = stream.readInt();
133 SharedSecrets.getJavaOISAccess().checkArray(stream, int[].class, numProfiles);
134 SharedSecrets.getJavaOISAccess().checkArray(stream, byte[].class, numProfiles);
135 profileTags = new int[numProfiles];
136 profileData = new byte[numProfiles][];
137 for (int i = 0; i < numProfiles; i++) {
138 profileTags[i] = stream.readInt();
139 int dataSize = stream.readInt();
140 SharedSecrets.getJavaOISAccess().checkArray(stream, byte[].class, dataSize);
141 profileData[i] = new byte[dataSize];
142 stream.readFully(profileData[i]);
143 }
144 }
146 public void doWrite( ObjectOutputStream stream )
147 throws IOException
148 {
149 // write the IOR to the ObjectOutputStream
150 stream.writeInt(typeData.length);
151 stream.write(typeData);
152 stream.writeInt(profileTags.length);
153 for (int i = 0; i < profileTags.length; i++) {
154 stream.writeInt(profileTags[i]);
155 stream.writeInt(profileData[i].length);
156 stream.write(profileData[i]);
157 }
158 }
160 /**
161 * Returns a hash code value for the object which is the same for all stubs
162 * that represent the same remote object.
163 * @return the hash code value.
164 */
165 public synchronized int hashCode()
166 {
167 if (hashCode == 0) {
169 // compute the hash code
170 for (int i = 0; i < typeData.length; i++) {
171 hashCode = hashCode * 37 + typeData[i];
172 }
174 for (int i = 0; i < profileTags.length; i++) {
175 hashCode = hashCode * 37 + profileTags[i];
176 for (int j = 0; j < profileData[i].length; j++) {
177 hashCode = hashCode * 37 + profileData[i][j];
178 }
179 }
180 }
182 return hashCode;
183 }
185 private boolean equalArrays( int[] data1, int[] data2 )
186 {
187 if (data1.length != data2.length)
188 return false ;
190 for (int ctr=0; ctr<data1.length; ctr++) {
191 if (data1[ctr] != data2[ctr])
192 return false ;
193 }
195 return true ;
196 }
198 private boolean equalArrays( byte[] data1, byte[] data2 )
199 {
200 if (data1.length != data2.length)
201 return false ;
203 for (int ctr=0; ctr<data1.length; ctr++) {
204 if (data1[ctr] != data2[ctr])
205 return false ;
206 }
208 return true ;
209 }
211 private boolean equalArrays( byte[][] data1, byte[][] data2 )
212 {
213 if (data1.length != data2.length)
214 return false ;
216 for (int ctr=0; ctr<data1.length; ctr++) {
217 if (!equalArrays( data1[ctr], data2[ctr] ))
218 return false ;
219 }
221 return true ;
222 }
224 public boolean equals(java.lang.Object obj)
225 {
226 if (this == obj) {
227 return true;
228 }
230 if (!(obj instanceof StubIORImpl)) {
231 return false;
232 }
234 StubIORImpl other = (StubIORImpl) obj;
235 if (other.hashCode() != this.hashCode()) {
236 return false;
237 }
239 return equalArrays( typeData, other.typeData ) &&
240 equalArrays( profileTags, other.profileTags ) &&
241 equalArrays( profileData, other.profileData ) ;
242 }
244 private void appendByteArray( StringBuffer result, byte[] data )
245 {
246 for ( int ctr=0; ctr<data.length; ctr++ ) {
247 result.append( Integer.toHexString( data[ctr] ) ) ;
248 }
249 }
251 /**
252 * Returns a string representation of this stub. Returns the same string
253 * for all stubs that represent the same remote object.
254 * "SimpleIORImpl[<typeName>,[<profileID>]data, ...]"
255 * @return a string representation of this stub.
256 */
257 public String toString()
258 {
259 StringBuffer result = new StringBuffer() ;
260 result.append( "SimpleIORImpl[" ) ;
261 String repositoryId = new String( typeData ) ;
262 result.append( repositoryId ) ;
263 for (int ctr=0; ctr<profileTags.length; ctr++) {
264 result.append( ",(" ) ;
265 result.append( profileTags[ctr] ) ;
266 result.append( ")" ) ;
267 appendByteArray( result, profileData[ctr] ) ;
268 }
270 result.append( "]" ) ;
271 return result.toString() ;
272 }
273 }