1 /*
2 * Copyright (c) 1998, 2010, 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
36 import java.util.Hashtable;
37 import java.io.IOException;
38
39 import com.sun.corba.se.impl.util.RepositoryId;
40 import com.sun.corba.se.impl.util.Utility;
41
42 import org.omg.CORBA.TCKind;
43
44 import org.omg.CORBA.portable.IndirectionException;
45 import com.sun.org.omg.SendingContext.CodeBase;
46 import com.sun.org.omg.SendingContext.CodeBaseHelper;
47
48 import java.security.AccessController;
49 import java.security.PrivilegedAction;
50 import java.security.PrivilegedExceptionAction;
51
52 import com.sun.corba.se.spi.logging.CORBALogDomains;
53 import com.sun.corba.se.impl.logging.OMGSystemException;
54 import com.sun.corba.se.impl.logging.UtilSystemException;
55
56 public class ValueHandlerImpl implements javax.rmi.CORBA.ValueHandlerMultiFormat {
57
58 // Property to override our maximum stream format version
59 public static final String FORMAT_VERSION_PROPERTY
60 = "com.sun.CORBA.MaxStreamFormatVersion";
61
62 private static final byte MAX_SUPPORTED_FORMAT_VERSION = (byte)2;
63 private static final byte STREAM_FORMAT_VERSION_1 = (byte)1;
64
65 // The ValueHandler's maximum stream format version to advertise,
66 // set in a static initializer.
67 private static final byte MAX_STREAM_FORMAT_VERSION;
68
69 static {
70 MAX_STREAM_FORMAT_VERSION = getMaxStreamFormatVersion();
71 }
72
73 // Looks for the FORMAT_VERSION_PROPERTY system property
74 // to allow the user to override our default stream format
75 // version. Note that this still only allows them to pick
76 // a supported version (1 through MAX_STREAM_FORMAT_VERSION).
133 return MAX_STREAM_FORMAT_VERSION;
134 }
135
136 // See javax.rmi.CORBA.ValueHandlerMultiFormat
137 public void writeValue(org.omg.CORBA.portable.OutputStream out,
138 java.io.Serializable value,
139 byte streamFormatVersion) {
140
141 if (streamFormatVersion == 2) {
142 if (!(out instanceof org.omg.CORBA.portable.ValueOutputStream)) {
143 throw omgWrapper.notAValueoutputstream() ;
144 }
145 } else if (streamFormatVersion != 1) {
146 throw omgWrapper.invalidStreamFormatVersion(
147 new Integer(streamFormatVersion) ) ;
148 }
149
150 writeValueWithVersion(out, value, streamFormatVersion);
151 }
152
153 public ValueHandlerImpl(){}
154
155 public ValueHandlerImpl(boolean isInputStream) {
156 this();
157 useHashtables = false;
158 this.isInputStream = isInputStream;
159 }
160
161 /**
162 * Writes the value to the stream using java semantics.
163 * @param out The stream to write the value to
164 * @param value The value to be written to the stream
165 **/
166 public void writeValue(org.omg.CORBA.portable.OutputStream _out,
167 java.io.Serializable value) {
168 writeValueWithVersion(_out, value, STREAM_FORMAT_VERSION_1);
169 }
170
171 private void writeValueWithVersion(org.omg.CORBA.portable.OutputStream _out,
172 java.io.Serializable value,
173 byte streamFormatVersion) {
174
175 org.omg.CORBA_2_3.portable.OutputStream out =
176 (org.omg.CORBA_2_3.portable.OutputStream) _out;
177
178 if (!useHashtables) {
179 if (outputStreamBridge == null) {
180 outputStreamBridge = createOutputStream();
441 public boolean isAbstractBase(Class clazz)
442 {
443 return RepositoryId.isAbstractBase(clazz);
444 }
445
446 public boolean isSequence(String id)
447 {
448 RepositoryId repId = RepositoryId.cache.getId(id);
449 return repId.isSequence();
450 }
451
452 /**
453 * If the value contains a writeReplace method then the result
454 * is returned. Otherwise, the value itself is returned.
455 * @return the true value to marshal on the wire.
456 **/
457 public java.io.Serializable writeReplace(java.io.Serializable value) {
458 return ObjectStreamClass.lookup(value.getClass()).writeReplace(value);
459 }
460
461 /**
462 * Encapsulates writing of Java char arrays so that the 1.3 subclass
463 * can override it without exposing internals across packages. This
464 * is a fix for bug 4367783.
465 */
466 protected void writeCharArray(org.omg.CORBA_2_3.portable.OutputStream out,
467 char[] array,
468 int offset,
469 int length)
470 {
471 out.write_wchar_array(array, offset, length);
472 }
473
474 private void write_Array(org.omg.CORBA_2_3.portable.OutputStream out, java.io.Serializable obj, Class type) {
475
476 int i, length;
477
478 if (type.isPrimitive()) {
479 if (type == Integer.TYPE) {
480 int[] array = (int[])((Object)obj);
481 length = array.length;
482 out.write_ulong(length);
483 out.write_long_array(array, 0, length);
484 } else if (type == Byte.TYPE) {
485 byte[] array = (byte[])((Object)obj);
486 length = array.length;
559 case kAbstractType:
560 Util.writeAbstractObject(out,array[i]);
561 break;
562 case kValueType:
563 try{
564 out.write_value((java.io.Serializable)array[i]);
565 } catch(ClassCastException cce){
566 if (array[i] instanceof java.io.Serializable)
567 throw cce;
568 else {
569 Utility.throwNotSerializableForCorba(
570 array[i].getClass().getName());
571 }
572 }
573 break;
574 }
575 }
576 }
577 }
578
579 /**
580 * Encapsulates reading of Java char arrays so that the 1.3 subclass
581 * can override it without exposing internals across packages. This
582 * is a fix for bug 4367783.
583 */
584 protected void readCharArray(org.omg.CORBA_2_3.portable.InputStream in,
585 char[] array,
586 int offset,
587 int length)
588 {
589 in.read_wchar_array(array, offset, length);
590 }
591
592 private java.lang.Object read_Array(IIOPInputStream bridge,
593 org.omg.CORBA_2_3.portable.InputStream in,
594 Class sequence,
595 com.sun.org.omg.SendingContext.CodeBase sender,
596 int offset)
597 {
598 try {
599 // Read length of coming array
600 int length = in.read_ulong();
601 int i;
602
603 if (sequence == null) {
604 for (i = 0; i < length; i++)
778 }
779 }
780
781 }
782
783 return ((java.io.Serializable)((Object)array));
784 }
785 } finally {
786 // We've completed deserializing this object. Any
787 // future indirections will be handled correctly at the
788 // CDR level. The ActiveRecursionManager only deals with
789 // objects currently being deserialized.
790 bridge.activeRecursionMgr.removeObject(offset);
791 }
792 }
793
794 private boolean isArray(String repId){
795 return RepositoryId.cache.getId(repId).isSequence();
796 }
797
798 protected String getOutputStreamClassName() {
799 return "com.sun.corba.se.impl.io.IIOPOutputStream";
800 }
801
802 private IIOPOutputStream createOutputStream() {
803 final String name = getOutputStreamClassName();
804 try {
805 IIOPOutputStream stream = createOutputStreamBuiltIn(name);
806 if (stream != null) {
807 return stream;
808 }
809 return createCustom(IIOPOutputStream.class, name);
810 } catch (Throwable t) {
811 // Throw exception under the carpet.
812 InternalError ie = new InternalError(
813 "Error loading " + name
814 );
815 ie.initCause(t);
816 throw ie;
817 }
818 }
826 ) throws Throwable {
827 try {
828 return AccessController.doPrivileged(
829 new PrivilegedExceptionAction<IIOPOutputStream>() {
830 public IIOPOutputStream run() throws IOException {
831 return createOutputStreamBuiltInNoPriv(name);
832 }
833 }
834 );
835 } catch (java.security.PrivilegedActionException exc) {
836 throw exc.getCause();
837 }
838 }
839
840 /**
841 * Returning null indicates a non-built is specified.
842 */
843 private IIOPOutputStream createOutputStreamBuiltInNoPriv(
844 final String name
845 ) throws IOException {
846 return
847 name.equals(
848 IIOPOutputStream
849 .class.getName()
850 ) ?
851 new IIOPOutputStream() :
852
853 name.equals(
854 com.sun.corba.se.impl.orbutil.IIOPOutputStream_1_3
855 .class.getName()
856 ) ?
857 new com.sun.corba.se.impl.orbutil.IIOPOutputStream_1_3() :
858
859 name.equals(
860 com.sun.corba.se.impl.orbutil.IIOPOutputStream_1_3_1
861 .class.getName()
862 ) ?
863 new com.sun.corba.se.impl.orbutil.IIOPOutputStream_1_3_1() :
864
865 null;
866 }
867
868 protected String getInputStreamClassName() {
869 return "com.sun.corba.se.impl.io.IIOPInputStream";
870 }
871
872 private IIOPInputStream createInputStream() {
873 final String name = getInputStreamClassName();
874 try {
875 IIOPInputStream stream = createInputStreamBuiltIn(name);
876 if (stream != null) {
877 return stream;
878 }
879 return createCustom(IIOPInputStream.class, name);
880 } catch (Throwable t) {
881 // Throw exception under the carpet.
882 InternalError ie = new InternalError(
883 "Error loading " + name
884 );
885 ie.initCause(t);
886 throw ie;
887 }
888 }
896 ) throws Throwable {
897 try {
898 return AccessController.doPrivileged(
899 new PrivilegedExceptionAction<IIOPInputStream>() {
900 public IIOPInputStream run() throws IOException {
901 return createInputStreamBuiltInNoPriv(name);
902 }
903 }
904 );
905 } catch (java.security.PrivilegedActionException exc) {
906 throw exc.getCause();
907 }
908 }
909
910 /**
911 * Returning null indicates a non-built is specified.
912 */
913 private IIOPInputStream createInputStreamBuiltInNoPriv(
914 final String name
915 ) throws IOException {
916 return
917 name.equals(
918 IIOPInputStream
919 .class.getName()
920 ) ?
921 new IIOPInputStream() :
922
923 name.equals(
924 com.sun.corba.se.impl.orbutil.IIOPInputStream_1_3
925 .class.getName()
926 ) ?
927 new com.sun.corba.se.impl.orbutil.IIOPInputStream_1_3() :
928
929 name.equals(
930 com.sun.corba.se.impl.orbutil.IIOPInputStream_1_3_1
931 .class.getName()
932 ) ?
933 new com.sun.corba.se.impl.orbutil.IIOPInputStream_1_3_1() :
934
935 null;
936 }
937
938 /**
939 * Create a custom implementation without privileges.
940 */
941 private <T> T createCustom(
942 final Class<T> type, final String className
943 ) throws Throwable {
944 // Note: We use the thread context or system ClassLoader here
945 // since we want to load classes outside of the
946 // core JDK when running J2EE Pure ORB and
947 // talking to Kestrel.
948 ClassLoader cl = Thread.currentThread().getContextClassLoader();
949 if (cl == null)
950 cl = ClassLoader.getSystemClassLoader();
951
952 Class<?> clazz = cl.loadClass(className);
953 Class<? extends T> streamClass = clazz.asSubclass(type);
954
955 // Since the ClassLoader should cache the class, this isn't
956 // as expensive as it looks.
957 return streamClass.newInstance();
958
959 }
960
961 /**
962 * Our JDK 1.3 and JDK 1.3.1 behavior subclasses override this.
963 * The correct behavior is for a Java char to map to a CORBA wchar,
964 * but our older code mapped it to a CORBA char.
965 */
966 protected TCKind getJavaCharTCKind() {
967 return TCKind.tk_wchar;
968 }
969 }
|
1 /*
2 * Copyright (c) 1998, 2012, 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
36 import java.util.Hashtable;
37 import java.io.IOException;
38
39 import com.sun.corba.se.impl.util.RepositoryId;
40 import com.sun.corba.se.impl.util.Utility;
41
42 import org.omg.CORBA.TCKind;
43
44 import org.omg.CORBA.portable.IndirectionException;
45 import com.sun.org.omg.SendingContext.CodeBase;
46 import com.sun.org.omg.SendingContext.CodeBaseHelper;
47
48 import java.security.AccessController;
49 import java.security.PrivilegedAction;
50 import java.security.PrivilegedExceptionAction;
51
52 import com.sun.corba.se.spi.logging.CORBALogDomains;
53 import com.sun.corba.se.impl.logging.OMGSystemException;
54 import com.sun.corba.se.impl.logging.UtilSystemException;
55
56 public final class ValueHandlerImpl implements javax.rmi.CORBA.ValueHandlerMultiFormat {
57
58 // Property to override our maximum stream format version
59 public static final String FORMAT_VERSION_PROPERTY
60 = "com.sun.CORBA.MaxStreamFormatVersion";
61
62 private static final byte MAX_SUPPORTED_FORMAT_VERSION = (byte)2;
63 private static final byte STREAM_FORMAT_VERSION_1 = (byte)1;
64
65 // The ValueHandler's maximum stream format version to advertise,
66 // set in a static initializer.
67 private static final byte MAX_STREAM_FORMAT_VERSION;
68
69 static {
70 MAX_STREAM_FORMAT_VERSION = getMaxStreamFormatVersion();
71 }
72
73 // Looks for the FORMAT_VERSION_PROPERTY system property
74 // to allow the user to override our default stream format
75 // version. Note that this still only allows them to pick
76 // a supported version (1 through MAX_STREAM_FORMAT_VERSION).
133 return MAX_STREAM_FORMAT_VERSION;
134 }
135
136 // See javax.rmi.CORBA.ValueHandlerMultiFormat
137 public void writeValue(org.omg.CORBA.portable.OutputStream out,
138 java.io.Serializable value,
139 byte streamFormatVersion) {
140
141 if (streamFormatVersion == 2) {
142 if (!(out instanceof org.omg.CORBA.portable.ValueOutputStream)) {
143 throw omgWrapper.notAValueoutputstream() ;
144 }
145 } else if (streamFormatVersion != 1) {
146 throw omgWrapper.invalidStreamFormatVersion(
147 new Integer(streamFormatVersion) ) ;
148 }
149
150 writeValueWithVersion(out, value, streamFormatVersion);
151 }
152
153 private ValueHandlerImpl(){}
154
155 private ValueHandlerImpl(boolean isInputStream) {
156 this();
157 useHashtables = false;
158 this.isInputStream = isInputStream;
159 }
160
161 static ValueHandlerImpl getInstance() {
162 return new ValueHandlerImpl();
163 }
164
165 static ValueHandlerImpl getInstance(boolean isInputStream) {
166 return new ValueHandlerImpl(isInputStream);
167 }
168
169 /**
170 * Writes the value to the stream using java semantics.
171 * @param out The stream to write the value to
172 * @param value The value to be written to the stream
173 **/
174 public void writeValue(org.omg.CORBA.portable.OutputStream _out,
175 java.io.Serializable value) {
176 writeValueWithVersion(_out, value, STREAM_FORMAT_VERSION_1);
177 }
178
179 private void writeValueWithVersion(org.omg.CORBA.portable.OutputStream _out,
180 java.io.Serializable value,
181 byte streamFormatVersion) {
182
183 org.omg.CORBA_2_3.portable.OutputStream out =
184 (org.omg.CORBA_2_3.portable.OutputStream) _out;
185
186 if (!useHashtables) {
187 if (outputStreamBridge == null) {
188 outputStreamBridge = createOutputStream();
449 public boolean isAbstractBase(Class clazz)
450 {
451 return RepositoryId.isAbstractBase(clazz);
452 }
453
454 public boolean isSequence(String id)
455 {
456 RepositoryId repId = RepositoryId.cache.getId(id);
457 return repId.isSequence();
458 }
459
460 /**
461 * If the value contains a writeReplace method then the result
462 * is returned. Otherwise, the value itself is returned.
463 * @return the true value to marshal on the wire.
464 **/
465 public java.io.Serializable writeReplace(java.io.Serializable value) {
466 return ObjectStreamClass.lookup(value.getClass()).writeReplace(value);
467 }
468
469 private void writeCharArray(org.omg.CORBA_2_3.portable.OutputStream out,
470 char[] array,
471 int offset,
472 int length)
473 {
474 out.write_wchar_array(array, offset, length);
475 }
476
477 private void write_Array(org.omg.CORBA_2_3.portable.OutputStream out, java.io.Serializable obj, Class type) {
478
479 int i, length;
480
481 if (type.isPrimitive()) {
482 if (type == Integer.TYPE) {
483 int[] array = (int[])((Object)obj);
484 length = array.length;
485 out.write_ulong(length);
486 out.write_long_array(array, 0, length);
487 } else if (type == Byte.TYPE) {
488 byte[] array = (byte[])((Object)obj);
489 length = array.length;
562 case kAbstractType:
563 Util.writeAbstractObject(out,array[i]);
564 break;
565 case kValueType:
566 try{
567 out.write_value((java.io.Serializable)array[i]);
568 } catch(ClassCastException cce){
569 if (array[i] instanceof java.io.Serializable)
570 throw cce;
571 else {
572 Utility.throwNotSerializableForCorba(
573 array[i].getClass().getName());
574 }
575 }
576 break;
577 }
578 }
579 }
580 }
581
582 private void readCharArray(org.omg.CORBA_2_3.portable.InputStream in,
583 char[] array,
584 int offset,
585 int length)
586 {
587 in.read_wchar_array(array, offset, length);
588 }
589
590 private java.lang.Object read_Array(IIOPInputStream bridge,
591 org.omg.CORBA_2_3.portable.InputStream in,
592 Class sequence,
593 com.sun.org.omg.SendingContext.CodeBase sender,
594 int offset)
595 {
596 try {
597 // Read length of coming array
598 int length = in.read_ulong();
599 int i;
600
601 if (sequence == null) {
602 for (i = 0; i < length; i++)
776 }
777 }
778
779 }
780
781 return ((java.io.Serializable)((Object)array));
782 }
783 } finally {
784 // We've completed deserializing this object. Any
785 // future indirections will be handled correctly at the
786 // CDR level. The ActiveRecursionManager only deals with
787 // objects currently being deserialized.
788 bridge.activeRecursionMgr.removeObject(offset);
789 }
790 }
791
792 private boolean isArray(String repId){
793 return RepositoryId.cache.getId(repId).isSequence();
794 }
795
796 private String getOutputStreamClassName() {
797 return "com.sun.corba.se.impl.io.IIOPOutputStream";
798 }
799
800 private IIOPOutputStream createOutputStream() {
801 final String name = getOutputStreamClassName();
802 try {
803 IIOPOutputStream stream = createOutputStreamBuiltIn(name);
804 if (stream != null) {
805 return stream;
806 }
807 return createCustom(IIOPOutputStream.class, name);
808 } catch (Throwable t) {
809 // Throw exception under the carpet.
810 InternalError ie = new InternalError(
811 "Error loading " + name
812 );
813 ie.initCause(t);
814 throw ie;
815 }
816 }
824 ) throws Throwable {
825 try {
826 return AccessController.doPrivileged(
827 new PrivilegedExceptionAction<IIOPOutputStream>() {
828 public IIOPOutputStream run() throws IOException {
829 return createOutputStreamBuiltInNoPriv(name);
830 }
831 }
832 );
833 } catch (java.security.PrivilegedActionException exc) {
834 throw exc.getCause();
835 }
836 }
837
838 /**
839 * Returning null indicates a non-built is specified.
840 */
841 private IIOPOutputStream createOutputStreamBuiltInNoPriv(
842 final String name
843 ) throws IOException {
844 return name.equals(IIOPOutputStream.class.getName()) ?
845 new IIOPOutputStream() : null;
846 }
847
848 private String getInputStreamClassName() {
849 return "com.sun.corba.se.impl.io.IIOPInputStream";
850 }
851
852 private IIOPInputStream createInputStream() {
853 final String name = getInputStreamClassName();
854 try {
855 IIOPInputStream stream = createInputStreamBuiltIn(name);
856 if (stream != null) {
857 return stream;
858 }
859 return createCustom(IIOPInputStream.class, name);
860 } catch (Throwable t) {
861 // Throw exception under the carpet.
862 InternalError ie = new InternalError(
863 "Error loading " + name
864 );
865 ie.initCause(t);
866 throw ie;
867 }
868 }
876 ) throws Throwable {
877 try {
878 return AccessController.doPrivileged(
879 new PrivilegedExceptionAction<IIOPInputStream>() {
880 public IIOPInputStream run() throws IOException {
881 return createInputStreamBuiltInNoPriv(name);
882 }
883 }
884 );
885 } catch (java.security.PrivilegedActionException exc) {
886 throw exc.getCause();
887 }
888 }
889
890 /**
891 * Returning null indicates a non-built is specified.
892 */
893 private IIOPInputStream createInputStreamBuiltInNoPriv(
894 final String name
895 ) throws IOException {
896 return name.equals(IIOPInputStream.class.getName()) ?
897 new IIOPInputStream() : null;
898 }
899
900 /**
901 * Create a custom implementation without privileges.
902 */
903 private <T> T createCustom(
904 final Class<T> type, final String className
905 ) throws Throwable {
906 // Note: We use the thread context or system ClassLoader here
907 // since we want to load classes outside of the
908 // core JDK when running J2EE Pure ORB and
909 // talking to Kestrel.
910 ClassLoader cl = Thread.currentThread().getContextClassLoader();
911 if (cl == null)
912 cl = ClassLoader.getSystemClassLoader();
913
914 Class<?> clazz = cl.loadClass(className);
915 Class<? extends T> streamClass = clazz.asSubclass(type);
916
917 // Since the ClassLoader should cache the class, this isn't
918 // as expensive as it looks.
919 return streamClass.newInstance();
920
921 }
922
923 TCKind getJavaCharTCKind() {
924 return TCKind.tk_wchar;
925 }
926 }
|