001 /*
002 * Copyright 1998-2004 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026 /*
027 * Licensed Materials - Property of IBM
028 * RMI-IIOP v1.0
029 * Copyright IBM Corp. 1998 1999 All Rights Reserved
030 *
031 */
032
033 package javax.rmi.CORBA;
034
035 import org.omg.CORBA.ORB;
036 import org.omg.CORBA.INITIALIZE;
037 import org.omg.CORBA_2_3.portable.ObjectImpl;
038
039 import java.io.IOException;
040 import java.rmi.RemoteException;
041 import java.io.File;
042 import java.io.FileInputStream;
043 import java.net.MalformedURLException;
044 import java.security.AccessController;
045 import java.security.PrivilegedAction;
046 import java.util.Properties;
047 import java.rmi.server.RMIClassLoader;
048
049 import com.sun.corba.se.impl.orbutil.GetPropertyAction;
050
051 /**
052 * Base class from which all RMI-IIOP stubs must inherit.
053 */
054 public abstract class Stub extends ObjectImpl implements
055 java.io.Serializable {
056
057 private static final long serialVersionUID = 1087775603798577179L;
058
059 // This can only be set at object construction time (no sync necessary).
060 private transient StubDelegate stubDelegate = null;
061 private static Class stubDelegateClass = null;
062 private static final String StubClassKey = "javax.rmi.CORBA.StubClass";
063 private static final String defaultStubImplName = "com.sun.corba.se.impl.javax.rmi.CORBA.StubDelegateImpl";
064
065 static {
066 Object stubDelegateInstance = (Object) createDelegateIfSpecified(
067 StubClassKey, defaultStubImplName);
068 if (stubDelegateInstance != null)
069 stubDelegateClass = stubDelegateInstance.getClass();
070
071 }
072
073 /**
074 * Returns a hash code value for the object which is the same for all stubs
075 * that represent the same remote object.
076 * @return the hash code value.
077 */
078 public int hashCode() {
079
080 if (stubDelegate == null) {
081 setDefaultDelegate();
082 }
083
084 if (stubDelegate != null) {
085 return stubDelegate.hashCode(this );
086 }
087
088 return 0;
089 }
090
091 /**
092 * Compares two stubs for equality. Returns <code>true</code> when used to compare stubs
093 * that represent the same remote object, and <code>false</code> otherwise.
094 * @param obj the reference object with which to compare.
095 * @return <code>true</code> if this object is the same as the <code>obj</code>
096 * argument; <code>false</code> otherwise.
097 */
098 public boolean equals(java.lang.Object obj) {
099
100 if (stubDelegate == null) {
101 setDefaultDelegate();
102 }
103
104 if (stubDelegate != null) {
105 return stubDelegate.equals(this , obj);
106 }
107
108 return false;
109 }
110
111 /**
112 * Returns a string representation of this stub. Returns the same string
113 * for all stubs that represent the same remote object.
114 * @return a string representation of this stub.
115 */
116 public String toString() {
117
118 if (stubDelegate == null) {
119 setDefaultDelegate();
120 }
121
122 String ior;
123 if (stubDelegate != null) {
124 ior = stubDelegate.toString(this );
125 if (ior == null) {
126 return super .toString();
127 } else {
128 return ior;
129 }
130 }
131 return super .toString();
132 }
133
134 /**
135 * Connects this stub to an ORB. Required after the stub is deserialized
136 * but not after it is demarshalled by an ORB stream. If an unconnected
137 * stub is passed to an ORB stream for marshalling, it is implicitly
138 * connected to that ORB. Application code should not call this method
139 * directly, but should call the portable wrapper method
140 * {@link javax.rmi.PortableRemoteObject#connect}.
141 * @param orb the ORB to connect to.
142 * @exception RemoteException if the stub is already connected to a different
143 * ORB, or if the stub does not represent an exported remote or local object.
144 */
145 public void connect(ORB orb) throws RemoteException {
146
147 if (stubDelegate == null) {
148 setDefaultDelegate();
149 }
150
151 if (stubDelegate != null) {
152 stubDelegate.connect(this , orb);
153 }
154
155 }
156
157 /**
158 * Serialization method to restore the IOR state.
159 */
160 private void readObject(java.io.ObjectInputStream stream)
161 throws IOException, ClassNotFoundException {
162
163 if (stubDelegate == null) {
164 setDefaultDelegate();
165 }
166
167 if (stubDelegate != null) {
168 stubDelegate.readObject(this , stream);
169 }
170
171 }
172
173 /**
174 * Serialization method to save the IOR state.
175 * @serialData The length of the IOR type ID (int), followed by the IOR type ID
176 * (byte array encoded using ISO8859-1), followed by the number of IOR profiles
177 * (int), followed by the IOR profiles. Each IOR profile is written as a
178 * profile tag (int), followed by the length of the profile data (int), followed
179 * by the profile data (byte array).
180 */
181 private void writeObject(java.io.ObjectOutputStream stream)
182 throws IOException {
183
184 if (stubDelegate == null) {
185 setDefaultDelegate();
186 }
187
188 if (stubDelegate != null) {
189 stubDelegate.writeObject(this , stream);
190 }
191 }
192
193 private void setDefaultDelegate() {
194 if (stubDelegateClass != null) {
195 try {
196 stubDelegate = (javax.rmi.CORBA.StubDelegate) stubDelegateClass
197 .newInstance();
198 } catch (Exception ex) {
199 // what kind of exception to throw
200 // delegate not set therefore it is null and will return default
201 // values
202 }
203 }
204 }
205
206 // Same code as in PortableRemoteObject. Can not be shared because they
207 // are in different packages and the visibility needs to be package for
208 // security reasons. If you know a better solution how to share this code
209 // then remove it from PortableRemoteObject. Also in Util.java
210 private static Object createDelegateIfSpecified(String classKey,
211 String defaultClassName) {
212 String className = (String) AccessController
213 .doPrivileged(new GetPropertyAction(classKey));
214 if (className == null) {
215 Properties props = getORBPropertiesFile();
216 if (props != null) {
217 className = props.getProperty(classKey);
218 }
219 }
220
221 if (className == null) {
222 className = defaultClassName;
223 }
224
225 try {
226 return loadDelegateClass(className).newInstance();
227 } catch (ClassNotFoundException ex) {
228 INITIALIZE exc = new INITIALIZE("Cannot instantiate "
229 + className);
230 exc.initCause(ex);
231 throw exc;
232 } catch (Exception ex) {
233 INITIALIZE exc = new INITIALIZE("Error while instantiating"
234 + className);
235 exc.initCause(ex);
236 throw exc;
237 }
238
239 }
240
241 private static Class loadDelegateClass(String className)
242 throws ClassNotFoundException {
243 try {
244 ClassLoader loader = Thread.currentThread()
245 .getContextClassLoader();
246 return Class.forName(className, false, loader);
247 } catch (ClassNotFoundException e) {
248 // ignore, then try RMIClassLoader
249 }
250
251 try {
252 return RMIClassLoader.loadClass(className);
253 } catch (MalformedURLException e) {
254 String msg = "Could not load " + className + ": "
255 + e.toString();
256 ClassNotFoundException exc = new ClassNotFoundException(msg);
257 throw exc;
258 }
259 }
260
261 /**
262 * Load the orb.properties file.
263 */
264 private static Properties getORBPropertiesFile() {
265 return (Properties) AccessController
266 .doPrivileged(new GetORBPropertiesFileAction());
267 }
268
269 }
|