src/share/classes/com/sun/corba/se/impl/io/InputStreamHook.java

Mon, 16 Oct 2017 15:59:03 +0800

author
aoqi
date
Mon, 16 Oct 2017 15:59:03 +0800
changeset 1022
6081f57a0021
parent 748
6845b95cba6b
permissions
-rw-r--r--

merge

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation. Oracle designates this
aoqi@0 8 * particular file as subject to the "Classpath" exception as provided
aoqi@0 9 * by Oracle in the LICENSE file that accompanied this code.
aoqi@0 10 *
aoqi@0 11 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 14 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 15 * accompanied this code).
aoqi@0 16 *
aoqi@0 17 * You should have received a copy of the GNU General Public License version
aoqi@0 18 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 20 *
aoqi@0 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 22 * or visit www.oracle.com if you need additional information or have any
aoqi@0 23 * questions.
aoqi@0 24 */
aoqi@0 25 /*
aoqi@0 26 * Licensed Materials - Property of IBM
aoqi@0 27 * RMI-IIOP v1.0
aoqi@0 28 * Copyright IBM Corp. 1998 1999 All Rights Reserved
aoqi@0 29 *
aoqi@0 30 */
aoqi@0 31
aoqi@0 32 package com.sun.corba.se.impl.io;
aoqi@0 33
aoqi@0 34 import java.io.IOException;
aoqi@0 35 import java.io.StreamCorruptedException;
aoqi@0 36 import java.io.NotActiveException;
aoqi@0 37 import java.io.InputStream;
aoqi@0 38 import java.io.ObjectInputStream;
aoqi@0 39 import java.util.*;
aoqi@0 40 import java.lang.reflect.Array;
aoqi@0 41 import java.lang.reflect.Constructor;
aoqi@0 42
aoqi@0 43 import org.omg.CORBA.portable.ValueInputStream;
aoqi@0 44
aoqi@0 45 import com.sun.corba.se.spi.orb.ORB;
aoqi@0 46 import com.sun.corba.se.spi.orb.ORBVersion;
aoqi@0 47 import com.sun.corba.se.spi.orb.ORBVersionFactory;
aoqi@0 48 import com.sun.corba.se.spi.logging.CORBALogDomains;
aoqi@0 49 import com.sun.corba.se.impl.logging.UtilSystemException;
aoqi@0 50 import com.sun.corba.se.impl.logging.OMGSystemException;
aoqi@0 51
aoqi@0 52 public abstract class InputStreamHook extends ObjectInputStream
aoqi@0 53 {
aoqi@0 54 // These should be visible in all the nested classes
aoqi@0 55 static final OMGSystemException omgWrapper =
aoqi@0 56 OMGSystemException.get( CORBALogDomains.RPC_ENCODING ) ;
aoqi@0 57
aoqi@0 58 static final UtilSystemException utilWrapper =
aoqi@0 59 UtilSystemException.get( CORBALogDomains.RPC_ENCODING ) ;
aoqi@0 60
aoqi@0 61 private class HookGetFields extends ObjectInputStream.GetField {
aoqi@0 62 private Map fields = null;
aoqi@0 63
aoqi@0 64 HookGetFields(Map fields){
aoqi@0 65 this.fields = fields;
aoqi@0 66 }
aoqi@0 67
aoqi@0 68 /**
aoqi@0 69 * Get the ObjectStreamClass that describes the fields in the stream.
aoqi@0 70 *
aoqi@0 71 * REVISIT! This doesn't work since we have our own ObjectStreamClass.
aoqi@0 72 */
aoqi@0 73 public java.io.ObjectStreamClass getObjectStreamClass() {
aoqi@0 74 return null;
aoqi@0 75 }
aoqi@0 76
aoqi@0 77 /**
aoqi@0 78 * Return true if the named field is defaulted and has no value
aoqi@0 79 * in this stream.
aoqi@0 80 */
aoqi@0 81 public boolean defaulted(String name)
aoqi@0 82 throws IOException, IllegalArgumentException {
aoqi@0 83 return (!fields.containsKey(name));
aoqi@0 84 }
aoqi@0 85
aoqi@0 86 /**
aoqi@0 87 * Get the value of the named boolean field from the persistent field.
aoqi@0 88 */
aoqi@0 89 public boolean get(String name, boolean defvalue)
aoqi@0 90 throws IOException, IllegalArgumentException {
aoqi@0 91 if (defaulted(name))
aoqi@0 92 return defvalue;
aoqi@0 93 else return ((Boolean)fields.get(name)).booleanValue();
aoqi@0 94 }
aoqi@0 95
aoqi@0 96 /**
aoqi@0 97 * Get the value of the named char field from the persistent fields.
aoqi@0 98 */
aoqi@0 99 public char get(String name, char defvalue)
aoqi@0 100 throws IOException, IllegalArgumentException {
aoqi@0 101 if (defaulted(name))
aoqi@0 102 return defvalue;
aoqi@0 103 else return ((Character)fields.get(name)).charValue();
aoqi@0 104
aoqi@0 105 }
aoqi@0 106
aoqi@0 107 /**
aoqi@0 108 * Get the value of the named byte field from the persistent fields.
aoqi@0 109 */
aoqi@0 110 public byte get(String name, byte defvalue)
aoqi@0 111 throws IOException, IllegalArgumentException {
aoqi@0 112 if (defaulted(name))
aoqi@0 113 return defvalue;
aoqi@0 114 else return ((Byte)fields.get(name)).byteValue();
aoqi@0 115
aoqi@0 116 }
aoqi@0 117
aoqi@0 118 /**
aoqi@0 119 * Get the value of the named short field from the persistent fields.
aoqi@0 120 */
aoqi@0 121 public short get(String name, short defvalue)
aoqi@0 122 throws IOException, IllegalArgumentException {
aoqi@0 123 if (defaulted(name))
aoqi@0 124 return defvalue;
aoqi@0 125 else return ((Short)fields.get(name)).shortValue();
aoqi@0 126
aoqi@0 127 }
aoqi@0 128
aoqi@0 129 /**
aoqi@0 130 * Get the value of the named int field from the persistent fields.
aoqi@0 131 */
aoqi@0 132 public int get(String name, int defvalue)
aoqi@0 133 throws IOException, IllegalArgumentException {
aoqi@0 134 if (defaulted(name))
aoqi@0 135 return defvalue;
aoqi@0 136 else return ((Integer)fields.get(name)).intValue();
aoqi@0 137
aoqi@0 138 }
aoqi@0 139
aoqi@0 140 /**
aoqi@0 141 * Get the value of the named long field from the persistent fields.
aoqi@0 142 */
aoqi@0 143 public long get(String name, long defvalue)
aoqi@0 144 throws IOException, IllegalArgumentException {
aoqi@0 145 if (defaulted(name))
aoqi@0 146 return defvalue;
aoqi@0 147 else return ((Long)fields.get(name)).longValue();
aoqi@0 148
aoqi@0 149 }
aoqi@0 150
aoqi@0 151 /**
aoqi@0 152 * Get the value of the named float field from the persistent fields.
aoqi@0 153 */
aoqi@0 154 public float get(String name, float defvalue)
aoqi@0 155 throws IOException, IllegalArgumentException {
aoqi@0 156 if (defaulted(name))
aoqi@0 157 return defvalue;
aoqi@0 158 else return ((Float)fields.get(name)).floatValue();
aoqi@0 159
aoqi@0 160 }
aoqi@0 161
aoqi@0 162 /**
aoqi@0 163 * Get the value of the named double field from the persistent field.
aoqi@0 164 */
aoqi@0 165 public double get(String name, double defvalue)
aoqi@0 166 throws IOException, IllegalArgumentException {
aoqi@0 167 if (defaulted(name))
aoqi@0 168 return defvalue;
aoqi@0 169 else return ((Double)fields.get(name)).doubleValue();
aoqi@0 170
aoqi@0 171 }
aoqi@0 172
aoqi@0 173 /**
aoqi@0 174 * Get the value of the named Object field from the persistent field.
aoqi@0 175 */
aoqi@0 176 public Object get(String name, Object defvalue)
aoqi@0 177 throws IOException, IllegalArgumentException {
aoqi@0 178 if (defaulted(name))
aoqi@0 179 return defvalue;
aoqi@0 180 else return fields.get(name);
aoqi@0 181
aoqi@0 182 }
aoqi@0 183
aoqi@0 184 public String toString(){
aoqi@0 185 return fields.toString();
aoqi@0 186 }
aoqi@0 187 }
aoqi@0 188
aoqi@0 189 public InputStreamHook()
aoqi@0 190 throws IOException {
aoqi@0 191 super();
aoqi@0 192 }
aoqi@0 193
aoqi@0 194 public void defaultReadObject()
aoqi@0 195 throws IOException, ClassNotFoundException, NotActiveException
aoqi@0 196 {
aoqi@0 197 readObjectState.beginDefaultReadObject(this);
aoqi@0 198
aoqi@0 199 defaultReadObjectDelegate();
aoqi@0 200
aoqi@0 201 readObjectState.endDefaultReadObject(this);
aoqi@0 202 }
aoqi@0 203
aoqi@0 204 abstract void defaultReadObjectDelegate();
aoqi@0 205
aoqi@0 206 abstract void readFields(java.util.Map fieldToValueMap)
aoqi@0 207 throws java.io.InvalidClassException, java.io.StreamCorruptedException,
aoqi@0 208 ClassNotFoundException, java.io.IOException;
aoqi@0 209
aoqi@0 210
aoqi@0 211 // See java.io.ObjectInputStream.GetField
aoqi@0 212 // Remember that this is equivalent to defaultReadObject
aoqi@0 213 // in RMI-IIOP
aoqi@0 214 public ObjectInputStream.GetField readFields()
aoqi@0 215 throws IOException, ClassNotFoundException, NotActiveException {
aoqi@0 216
aoqi@0 217 HashMap fieldValueMap = new HashMap();
aoqi@0 218
aoqi@0 219 // We were treating readFields same as defaultReadObject. It is
aoqi@0 220 // incorrect if the state is readOptionalData. If this line
aoqi@0 221 // is uncommented, it will throw a stream corrupted exception.
aoqi@0 222 // _REVISIT_: The ideal fix would be to add a new state. In
aoqi@0 223 // writeObject user may do one of the following
aoqi@0 224 // 1. Call defaultWriteObject()
aoqi@0 225 // 2. Put out optional fields
aoqi@0 226 // 3. Call writeFields
aoqi@0 227 // We have the state defined for (1) and (2) but not for (3), so
aoqi@0 228 // we should ideally introduce a new state for 3 and have the
aoqi@0 229 // beginDefaultReadObject do nothing.
aoqi@0 230 //readObjectState.beginDefaultReadObject(this);
aoqi@0 231
aoqi@0 232 readFields(fieldValueMap);
aoqi@0 233
aoqi@0 234 readObjectState.endDefaultReadObject(this);
aoqi@0 235
aoqi@0 236 return new HookGetFields(fieldValueMap);
aoqi@0 237 }
aoqi@0 238
aoqi@0 239 // The following is a State pattern implementation of what
aoqi@0 240 // should be done when the sender's Serializable has a
aoqi@0 241 // writeObject method. This was especially necessary for
aoqi@0 242 // RMI-IIOP stream format version 2. Please see the
aoqi@0 243 // state diagrams in the docs directory of the workspace.
aoqi@0 244 //
aoqi@0 245 // On the reader's side, the main factors are whether or not
aoqi@0 246 // we have a readObject method and whether or not the
aoqi@0 247 // sender wrote default data
aoqi@0 248
aoqi@0 249 protected void setState(ReadObjectState newState) {
aoqi@0 250 readObjectState = newState;
aoqi@0 251 }
aoqi@0 252
aoqi@0 253 protected abstract byte getStreamFormatVersion();
aoqi@0 254 abstract org.omg.CORBA_2_3.portable.InputStream getOrbStream();
aoqi@0 255
aoqi@0 256 // Description of possible actions
aoqi@0 257 protected static class ReadObjectState {
aoqi@0 258 public void beginUnmarshalCustomValue(InputStreamHook stream,
aoqi@0 259 boolean calledDefaultWriteObject,
aoqi@0 260 boolean hasReadObject) throws IOException {}
aoqi@0 261
aoqi@0 262 public void endUnmarshalCustomValue(InputStreamHook stream) throws IOException {}
aoqi@0 263 public void beginDefaultReadObject(InputStreamHook stream) throws IOException {}
aoqi@0 264 public void endDefaultReadObject(InputStreamHook stream) throws IOException {}
aoqi@0 265 public void readData(InputStreamHook stream) throws IOException {}
aoqi@0 266 }
aoqi@0 267
aoqi@0 268 protected ReadObjectState readObjectState = DEFAULT_STATE;
aoqi@0 269
aoqi@0 270 protected static final ReadObjectState DEFAULT_STATE = new DefaultState();
aoqi@0 271 protected static final ReadObjectState IN_READ_OBJECT_OPT_DATA
aoqi@0 272 = new InReadObjectOptionalDataState();
aoqi@0 273 protected static final ReadObjectState IN_READ_OBJECT_NO_MORE_OPT_DATA
aoqi@0 274 = new InReadObjectNoMoreOptionalDataState();
aoqi@0 275 protected static final ReadObjectState IN_READ_OBJECT_DEFAULTS_SENT
aoqi@0 276 = new InReadObjectDefaultsSentState();
aoqi@0 277 protected static final ReadObjectState NO_READ_OBJECT_DEFAULTS_SENT
aoqi@0 278 = new NoReadObjectDefaultsSentState();
aoqi@0 279
aoqi@0 280 protected static final ReadObjectState IN_READ_OBJECT_REMOTE_NOT_CUSTOM_MARSHALED
aoqi@0 281 = new InReadObjectRemoteDidNotUseWriteObjectState();
aoqi@0 282 protected static final ReadObjectState IN_READ_OBJECT_PAST_DEFAULTS_REMOTE_NOT_CUSTOM
aoqi@0 283 = new InReadObjectPastDefaultsRemoteDidNotUseWOState();
aoqi@0 284
aoqi@0 285 protected static class DefaultState extends ReadObjectState {
aoqi@0 286
aoqi@0 287 public void beginUnmarshalCustomValue(InputStreamHook stream,
aoqi@0 288 boolean calledDefaultWriteObject,
aoqi@0 289 boolean hasReadObject)
aoqi@0 290 throws IOException {
aoqi@0 291
aoqi@0 292 if (hasReadObject) {
aoqi@0 293 if (calledDefaultWriteObject)
aoqi@0 294 stream.setState(IN_READ_OBJECT_DEFAULTS_SENT);
aoqi@0 295 else {
aoqi@0 296 try {
aoqi@0 297 if (stream.getStreamFormatVersion() == 2)
aoqi@0 298 ((ValueInputStream)stream.getOrbStream()).start_value();
aoqi@0 299 } catch( Exception e ) {
aoqi@0 300 // This will happen for Big Integer which uses
aoqi@0 301 // writeFields in it's writeObject. We should be past
aoqi@0 302 // start_value by now.
aoqi@0 303 // NOTE: If we don't log any exception here we should
aoqi@0 304 // be fine. If there is an error, it will be caught
aoqi@0 305 // while reading the optional data.
aoqi@0 306
aoqi@0 307 }
aoqi@0 308 stream.setState(IN_READ_OBJECT_OPT_DATA);
aoqi@0 309 }
aoqi@0 310 } else {
aoqi@0 311 if (calledDefaultWriteObject)
aoqi@0 312 stream.setState(NO_READ_OBJECT_DEFAULTS_SENT);
aoqi@0 313 else
aoqi@0 314 // XXX I18N and logging needed.
aoqi@0 315 throw new StreamCorruptedException("No default data sent");
aoqi@0 316 }
aoqi@0 317 }
aoqi@0 318 }
aoqi@0 319
aoqi@0 320 // REVISIT. If a readObject exits here without reading
aoqi@0 321 // default data, we won't skip it. This could be done automatically
aoqi@0 322 // as in line 1492 in IIOPInputStream.
aoqi@0 323 protected static class InReadObjectRemoteDidNotUseWriteObjectState extends ReadObjectState {
aoqi@0 324
aoqi@0 325 public void beginUnmarshalCustomValue(InputStreamHook stream,
aoqi@0 326 boolean calledDefaultWriteObject,
aoqi@0 327 boolean hasReadObject)
aoqi@0 328 {
aoqi@0 329 throw utilWrapper.badBeginUnmarshalCustomValue() ;
aoqi@0 330 }
aoqi@0 331
aoqi@0 332 public void endDefaultReadObject(InputStreamHook stream) {
aoqi@0 333 stream.setState(IN_READ_OBJECT_PAST_DEFAULTS_REMOTE_NOT_CUSTOM);
aoqi@0 334 }
aoqi@0 335
aoqi@0 336 public void readData(InputStreamHook stream) {
aoqi@0 337 stream.throwOptionalDataIncompatibleException();
aoqi@0 338 }
aoqi@0 339 }
aoqi@0 340
aoqi@0 341 protected static class InReadObjectPastDefaultsRemoteDidNotUseWOState extends ReadObjectState {
aoqi@0 342
aoqi@0 343 public void beginUnmarshalCustomValue(InputStreamHook stream,
aoqi@0 344 boolean calledDefaultWriteObject,
aoqi@0 345 boolean hasReadObject)
aoqi@0 346 {
aoqi@0 347 throw utilWrapper.badBeginUnmarshalCustomValue() ;
aoqi@0 348 }
aoqi@0 349
aoqi@0 350 public void beginDefaultReadObject(InputStreamHook stream) throws IOException
aoqi@0 351 {
aoqi@0 352 // XXX I18N and logging needed.
aoqi@0 353 throw new StreamCorruptedException("Default data already read");
aoqi@0 354 }
aoqi@0 355
aoqi@0 356
aoqi@0 357 public void readData(InputStreamHook stream) {
aoqi@0 358 stream.throwOptionalDataIncompatibleException();
aoqi@0 359 }
aoqi@0 360 }
aoqi@0 361
aoqi@0 362 protected void throwOptionalDataIncompatibleException()
aoqi@0 363 {
aoqi@0 364 throw omgWrapper.rmiiiopOptionalDataIncompatible2() ;
aoqi@0 365 }
aoqi@0 366
aoqi@0 367
aoqi@0 368 protected static class InReadObjectDefaultsSentState extends ReadObjectState {
aoqi@0 369
aoqi@0 370 public void beginUnmarshalCustomValue(InputStreamHook stream,
aoqi@0 371 boolean calledDefaultWriteObject,
aoqi@0 372 boolean hasReadObject) {
aoqi@0 373 // This should never happen.
aoqi@0 374 throw utilWrapper.badBeginUnmarshalCustomValue() ;
aoqi@0 375 }
aoqi@0 376
aoqi@0 377 public void endUnmarshalCustomValue(InputStreamHook stream) {
aoqi@0 378
aoqi@0 379 // In stream format version 2, we can skip over
aoqi@0 380 // the optional data this way. In stream format version 1,
aoqi@0 381 // we will probably wind up with an error if we're
aoqi@0 382 // unmarshaling a superclass.
aoqi@0 383 if (stream.getStreamFormatVersion() == 2) {
aoqi@0 384 ((ValueInputStream)stream.getOrbStream()).start_value();
aoqi@0 385 ((ValueInputStream)stream.getOrbStream()).end_value();
aoqi@0 386 }
aoqi@0 387
aoqi@0 388 stream.setState(DEFAULT_STATE);
aoqi@0 389 }
aoqi@0 390
aoqi@0 391 public void endDefaultReadObject(InputStreamHook stream) throws IOException {
aoqi@0 392
aoqi@0 393 // Read the fake valuetype header in stream format version 2
aoqi@0 394 if (stream.getStreamFormatVersion() == 2)
aoqi@0 395 ((ValueInputStream)stream.getOrbStream()).start_value();
aoqi@0 396
aoqi@0 397 stream.setState(IN_READ_OBJECT_OPT_DATA);
aoqi@0 398 }
aoqi@0 399
aoqi@0 400 public void readData(InputStreamHook stream) throws IOException {
aoqi@0 401 org.omg.CORBA.ORB orb = stream.getOrbStream().orb();
aoqi@0 402 if ((orb == null) ||
aoqi@0 403 !(orb instanceof com.sun.corba.se.spi.orb.ORB)) {
aoqi@0 404 throw new StreamCorruptedException(
aoqi@0 405 "Default data must be read first");
aoqi@0 406 }
aoqi@0 407 ORBVersion clientOrbVersion =
aoqi@0 408 ((com.sun.corba.se.spi.orb.ORB)orb).getORBVersion();
aoqi@0 409
aoqi@0 410 // Fix Date interop bug. For older versions of the ORB don't do
aoqi@0 411 // anything for readData(). Before this used to throw
aoqi@0 412 // StreamCorruptedException for older versions of the ORB where
aoqi@0 413 // calledDefaultWriteObject always returns true.
aoqi@0 414 if ((ORBVersionFactory.getPEORB().compareTo(clientOrbVersion) <= 0) ||
aoqi@0 415 (clientOrbVersion.equals(ORBVersionFactory.getFOREIGN()))) {
aoqi@0 416 // XXX I18N and logging needed.
aoqi@0 417 throw new StreamCorruptedException("Default data must be read first");
aoqi@0 418 }
aoqi@0 419 }
aoqi@0 420 }
aoqi@0 421
aoqi@0 422 protected static class InReadObjectOptionalDataState extends ReadObjectState {
aoqi@0 423
aoqi@0 424 public void beginUnmarshalCustomValue(InputStreamHook stream,
aoqi@0 425 boolean calledDefaultWriteObject,
aoqi@0 426 boolean hasReadObject)
aoqi@0 427 {
aoqi@0 428 // This should never happen.
aoqi@0 429 throw utilWrapper.badBeginUnmarshalCustomValue() ;
aoqi@0 430 }
aoqi@0 431
aoqi@0 432 public void endUnmarshalCustomValue(InputStreamHook stream) throws IOException
aoqi@0 433 {
aoqi@0 434 if (stream.getStreamFormatVersion() == 2) {
aoqi@0 435 ((ValueInputStream)stream.getOrbStream()).end_value();
aoqi@0 436 }
aoqi@0 437 stream.setState(DEFAULT_STATE);
aoqi@0 438 }
aoqi@0 439
aoqi@0 440 public void beginDefaultReadObject(InputStreamHook stream) throws IOException
aoqi@0 441 {
aoqi@0 442 // XXX I18N and logging needed.
aoqi@0 443 throw new StreamCorruptedException("Default data not sent or already read/passed");
aoqi@0 444 }
aoqi@0 445
aoqi@0 446
aoqi@0 447 }
aoqi@0 448
aoqi@0 449 protected static class InReadObjectNoMoreOptionalDataState
aoqi@0 450 extends InReadObjectOptionalDataState {
aoqi@0 451
aoqi@0 452 public void readData(InputStreamHook stream) throws IOException {
aoqi@0 453 stream.throwOptionalDataIncompatibleException();
aoqi@0 454 }
aoqi@0 455 }
aoqi@0 456
aoqi@0 457 protected static class NoReadObjectDefaultsSentState extends ReadObjectState {
aoqi@0 458 public void endUnmarshalCustomValue(InputStreamHook stream) throws IOException {
aoqi@0 459 // Code should read default fields before calling this
aoqi@0 460
aoqi@0 461 if (stream.getStreamFormatVersion() == 2) {
aoqi@0 462 ((ValueInputStream)stream.getOrbStream()).start_value();
aoqi@0 463 ((ValueInputStream)stream.getOrbStream()).end_value();
aoqi@0 464 }
aoqi@0 465
aoqi@0 466 stream.setState(DEFAULT_STATE);
aoqi@0 467 }
aoqi@0 468 }
aoqi@0 469 }

mercurial