View Javadoc
1   /*
2    * Copyright (c) 2003, 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   */
31  
32  package com.sun.corba.se.impl.ior;
33  
34  import java.io.ObjectInputStream ;
35  import java.io.ObjectOutputStream ;
36  import java.io.IOException ;
37  import java.io.StringWriter ;
38  
39  import org.omg.CORBA.ORB ;
40  
41  import org.omg.CORBA.portable.Delegate ;
42  import org.omg.CORBA.portable.InputStream ;
43  import org.omg.CORBA.portable.OutputStream ;
44  
45  // Be very careful: com.sun.corba imports must not depend on
46  // PEORB internal classes in ways that prevent portability to
47  // other vendor's ORBs.
48  import com.sun.corba.se.spi.presentation.rmi.StubAdapter ;
49  import com.sun.corba.se.impl.orbutil.HexOutputStream ;
50  
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;
60  
61      // IOR components
62      private byte[] typeData;
63      private int[] profileTags;
64      private byte[][] profileData;
65  
66      public StubIORImpl()
67      {
68          hashCode = 0 ;
69          typeData = null ;
70          profileTags = null ;
71          profileData = null ;
72      }
73  
74      public String getRepositoryId()
75      {
76          if (typeData == null)
77              return null ;
78  
79          return new String( typeData ) ;
80      }
81  
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();
88  
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     }
102 
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         }
115 
116         InputStream istr = ostr.create_input_stream() ;
117 
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     }
122 
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         typeData = new byte[typeLength];
129         stream.readFully(typeData);
130         int numProfiles = stream.readInt();
131         profileTags = new int[numProfiles];
132         profileData = new byte[numProfiles][];
133         for (int i = 0; i < numProfiles; i++) {
134             profileTags[i] = stream.readInt();
135             profileData[i] = new byte[stream.readInt()];
136             stream.readFully(profileData[i]);
137         }
138     }
139 
140     public  void doWrite( ObjectOutputStream stream )
141         throws IOException
142     {
143         // write the IOR to the ObjectOutputStream
144         stream.writeInt(typeData.length);
145         stream.write(typeData);
146         stream.writeInt(profileTags.length);
147         for (int i = 0; i < profileTags.length; i++) {
148             stream.writeInt(profileTags[i]);
149             stream.writeInt(profileData[i].length);
150             stream.write(profileData[i]);
151         }
152     }
153 
154     /**
155      * Returns a hash code value for the object which is the same for all stubs
156      * that represent the same remote object.
157      * @return the hash code value.
158      */
159     public synchronized int hashCode()
160     {
161         if (hashCode == 0) {
162 
163             // compute the hash code
164             for (int i = 0; i < typeData.length; i++) {
165                 hashCode = hashCode * 37 + typeData[i];
166             }
167 
168             for (int i = 0; i < profileTags.length; i++) {
169                 hashCode = hashCode * 37 + profileTags[i];
170                 for (int j = 0; j < profileData[i].length; j++) {
171                     hashCode = hashCode * 37 + profileData[i][j];
172                 }
173             }
174         }
175 
176         return hashCode;
177     }
178 
179     private boolean equalArrays( int[] data1, int[] data2 )
180     {
181         if (data1.length != data2.length)
182             return false ;
183 
184         for (int ctr=0; ctr<data1.length; ctr++) {
185             if (data1[ctr] != data2[ctr])
186                 return false ;
187         }
188 
189         return true ;
190     }
191 
192     private boolean equalArrays( byte[] data1, byte[] data2 )
193     {
194         if (data1.length != data2.length)
195             return false ;
196 
197         for (int ctr=0; ctr<data1.length; ctr++) {
198             if (data1[ctr] != data2[ctr])
199                 return false ;
200         }
201 
202         return true ;
203     }
204 
205     private boolean equalArrays( byte[][] data1, byte[][] data2 )
206     {
207         if (data1.length != data2.length)
208             return false ;
209 
210         for (int ctr=0; ctr<data1.length; ctr++) {
211             if (!equalArrays( data1[ctr], data2[ctr] ))
212                 return false ;
213         }
214 
215         return true ;
216     }
217 
218     public boolean equals(java.lang.Object obj)
219     {
220         if (this == obj) {
221             return true;
222         }
223 
224         if (!(obj instanceof StubIORImpl)) {
225             return false;
226         }
227 
228         StubIORImpl other = (StubIORImpl) obj;
229         if (other.hashCode() != this.hashCode()) {
230             return false;
231         }
232 
233         return equalArrays( typeData, other.typeData ) &&
234             equalArrays( profileTags, other.profileTags ) &&
235             equalArrays( profileData, other.profileData ) ;
236     }
237 
238     private void appendByteArray( StringBuffer result, byte[] data )
239     {
240         for ( int ctr=0; ctr<data.length; ctr++ ) {
241             result.append( Integer.toHexString( data[ctr] ) ) ;
242         }
243     }
244 
245     /**
246      * Returns a string representation of this stub. Returns the same string
247      * for all stubs that represent the same remote object.
248      * "SimpleIORImpl[<typeName>,[<profileID>]data, ...]"
249      * @return a string representation of this stub.
250      */
251     public String toString()
252     {
253         StringBuffer result = new StringBuffer() ;
254         result.append( "SimpleIORImpl[" ) ;
255         String repositoryId = new String( typeData ) ;
256         result.append( repositoryId ) ;
257         for (int ctr=0; ctr<profileTags.length; ctr++) {
258             result.append( ",(" ) ;
259             result.append( profileTags[ctr] ) ;
260             result.append( ")" ) ;
261             appendByteArray( result,  profileData[ctr] ) ;
262         }
263 
264         result.append( "]" ) ;
265         return result.toString() ;
266     }
267 }