DynAnyUtil.java revision 608:7e06bf1dcb09
1/*
2 * Copyright (c) 2000, 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
26package com.sun.corba.se.impl.dynamicany;
27
28import org.omg.CORBA.Any;
29import org.omg.CORBA.TypeCode;
30import org.omg.CORBA.TCKind;
31import org.omg.CORBA.portable.OutputStream;
32//import org.omg.CORBA.ORBPackage.*;
33import org.omg.CORBA.TypeCodePackage.BadKind;
34import org.omg.CORBA.TypeCodePackage.Bounds;
35import org.omg.CORBA.portable.InputStream;
36import org.omg.DynamicAny.*;
37import org.omg.DynamicAny.DynAnyPackage.TypeMismatch;
38import org.omg.DynamicAny.DynAnyFactoryPackage.InconsistentTypeCode;
39import java.math.BigDecimal;
40import com.sun.corba.se.impl.corba.AnyImpl;
41
42import com.sun.corba.se.spi.orb.ORB ;
43import com.sun.corba.se.spi.logging.CORBALogDomains ;
44import com.sun.corba.se.impl.logging.ORBUtilSystemException ;
45
46public class DynAnyUtil
47{
48    static boolean isConsistentType(TypeCode typeCode) {
49        int kind = typeCode.kind().value();
50        return (kind != TCKind._tk_Principal &&
51                kind != TCKind._tk_native &&
52                kind != TCKind._tk_abstract_interface);
53    }
54
55    static boolean isConstructedDynAny(DynAny dynAny) {
56        // DynFixed is constructed but not a subclass of DynAnyConstructedImpl
57        //return (dynAny instanceof DynAnyConstructedImpl);
58        int kind = dynAny.type().kind().value();
59        return (kind == TCKind._tk_sequence ||
60                kind == TCKind._tk_struct ||
61                kind == TCKind._tk_array ||
62                kind == TCKind._tk_union ||
63                kind == TCKind._tk_enum ||
64                kind == TCKind._tk_fixed ||
65                kind == TCKind._tk_value ||
66                kind == TCKind._tk_value_box);
67    }
68
69    static DynAny createMostDerivedDynAny(Any any, ORB orb, boolean copyValue)
70        throws org.omg.DynamicAny.DynAnyFactoryPackage.InconsistentTypeCode
71    {
72        if (any == null || ! DynAnyUtil.isConsistentType(any.type()))
73            throw new org.omg.DynamicAny.DynAnyFactoryPackage.InconsistentTypeCode();
74
75        switch (any.type().kind().value()) {
76            case TCKind._tk_sequence:
77                return new DynSequenceImpl(orb, any, copyValue);
78            case TCKind._tk_struct:
79                return new DynStructImpl(orb, any, copyValue);
80            case TCKind._tk_array:
81                return new DynArrayImpl(orb, any, copyValue);
82            case TCKind._tk_union:
83                return new DynUnionImpl(orb, any, copyValue);
84            case TCKind._tk_enum:
85                return new DynEnumImpl(orb, any, copyValue);
86            case TCKind._tk_fixed:
87                return new DynFixedImpl(orb, any, copyValue);
88            case TCKind._tk_value:
89                return new DynValueImpl(orb, any, copyValue);
90            case TCKind._tk_value_box:
91                return new DynValueBoxImpl(orb, any, copyValue);
92            default:
93                return new DynAnyBasicImpl(orb, any, copyValue);
94        }
95    }
96
97    static DynAny createMostDerivedDynAny(TypeCode typeCode, ORB orb)
98        throws org.omg.DynamicAny.DynAnyFactoryPackage.InconsistentTypeCode
99    {
100        if (typeCode == null || ! DynAnyUtil.isConsistentType(typeCode))
101            throw new org.omg.DynamicAny.DynAnyFactoryPackage.InconsistentTypeCode();
102
103        switch (typeCode.kind().value()) {
104            case TCKind._tk_sequence:
105                return new DynSequenceImpl(orb, typeCode);
106            case TCKind._tk_struct:
107                return new DynStructImpl(orb, typeCode);
108            case TCKind._tk_array:
109                return new DynArrayImpl(orb, typeCode);
110            case TCKind._tk_union:
111                return new DynUnionImpl(orb, typeCode);
112            case TCKind._tk_enum:
113                return new DynEnumImpl(orb, typeCode);
114            case TCKind._tk_fixed:
115                return new DynFixedImpl(orb, typeCode);
116            case TCKind._tk_value:
117                return new DynValueImpl(orb, typeCode);
118            case TCKind._tk_value_box:
119                return new DynValueBoxImpl(orb, typeCode);
120            default:
121                return new DynAnyBasicImpl(orb, typeCode);
122        }
123    }
124
125    // Extracts a member value according to the given TypeCode from the given complex Any
126    // (at the Anys current internal stream position, consuming the anys stream on the way)
127    // and returns it wrapped into a new Any
128/*
129    static Any extractAnyFromAny(TypeCode memberType, Any any, ORB orb) {
130        // Moved this functionality into AnyImpl because it is needed for Any.equal()
131        return ((AnyImpl)any).extractAny(memberType, orb);
132    }
133*/
134
135    // Extracts a member value according to the given TypeCode from the given complex Any
136    // (at the Anys current internal stream position, consuming the anys stream on the way)
137    // and returns it wrapped into a new Any
138    static Any extractAnyFromStream(TypeCode memberType, InputStream input, ORB orb) {
139        return AnyImpl.extractAnyFromStream(memberType, input, orb);
140    }
141
142    // Creates a default Any of the given type.
143    static Any createDefaultAnyOfType(TypeCode typeCode, ORB orb) {
144        ORBUtilSystemException wrapper = ORBUtilSystemException.get( orb,
145            CORBALogDomains.RPC_PRESENTATION ) ;
146
147        Any returnValue = orb.create_any();
148        // The spec for DynAny differs from Any on initialization via type code:
149        // - false for boolean
150        // - zero for numeric types
151        // - zero for types octet, char, and wchar
152        // - the empty string for string and wstring
153        // - nil for object references
154        // - a type code with a TCKind value of tk_null for type codes
155        // - for Any values, an Any containing a type code with a TCKind value of tk_null
156        //   type and no value
157        switch (typeCode.kind().value()) {
158            case TCKind._tk_boolean:
159                // false for boolean
160                returnValue.insert_boolean(false);
161                break;
162            case TCKind._tk_short:
163                // zero for numeric types
164                returnValue.insert_short((short)0);
165                break;
166            case TCKind._tk_ushort:
167                // zero for numeric types
168                returnValue.insert_ushort((short)0);
169                break;
170            case TCKind._tk_long:
171                // zero for numeric types
172                returnValue.insert_long(0);
173                break;
174            case TCKind._tk_ulong:
175                // zero for numeric types
176                returnValue.insert_ulong(0);
177                break;
178            case TCKind._tk_longlong:
179                // zero for numeric types
180                returnValue.insert_longlong((long)0);
181                break;
182            case TCKind._tk_ulonglong:
183                // zero for numeric types
184                returnValue.insert_ulonglong((long)0);
185                break;
186            case TCKind._tk_float:
187                // zero for numeric types
188                returnValue.insert_float((float)0.0);
189                break;
190            case TCKind._tk_double:
191                // zero for numeric types
192                returnValue.insert_double((double)0.0);
193                break;
194            case TCKind._tk_octet:
195                // zero for types octet, char, and wchar
196                returnValue.insert_octet((byte)0);
197                break;
198            case TCKind._tk_char:
199                // zero for types octet, char, and wchar
200                returnValue.insert_char((char)0);
201                break;
202            case TCKind._tk_wchar:
203                // zero for types octet, char, and wchar
204                returnValue.insert_wchar((char)0);
205                break;
206            case TCKind._tk_string:
207                // the empty string for string and wstring
208                // Make sure that type code for bounded strings gets respected
209                returnValue.type(typeCode);
210                // Doesn't erase the type of bounded string
211                returnValue.insert_string("");
212                break;
213            case TCKind._tk_wstring:
214                // the empty string for string and wstring
215                // Make sure that type code for bounded strings gets respected
216                returnValue.type(typeCode);
217                // Doesn't erase the type of bounded string
218                returnValue.insert_wstring("");
219                break;
220            case TCKind._tk_objref:
221                // nil for object references
222                returnValue.insert_Object(null);
223                break;
224            case TCKind._tk_TypeCode:
225                // a type code with a TCKind value of tk_null for type codes
226                // We can reuse the type code that's already in the any.
227                returnValue.insert_TypeCode(returnValue.type());
228                break;
229            case TCKind._tk_any:
230                // for Any values, an Any containing a type code with a TCKind value
231                // of tk_null type and no value.
232                // This is exactly what the default AnyImpl constructor provides.
233                // _REVISIT_ Note that this inner Any is considered uninitialized.
234                returnValue.insert_any(orb.create_any());
235                break;
236            case TCKind._tk_struct:
237            case TCKind._tk_union:
238            case TCKind._tk_enum:
239            case TCKind._tk_sequence:
240            case TCKind._tk_array:
241            case TCKind._tk_except:
242            case TCKind._tk_value:
243            case TCKind._tk_value_box:
244                // There are no default value for complex types since there is no
245                // concept of a hierarchy of Anys. Only DynAnys can be arrange in
246                // a hierarchy to mirror the TypeCode hierarchy.
247                // See DynAnyConstructedImpl.initializeComponentsFromTypeCode()
248                // on how this DynAny hierarchy is created from TypeCodes.
249                returnValue.type(typeCode);
250                break;
251            case TCKind._tk_fixed:
252                returnValue.insert_fixed(new BigDecimal("0.0"), typeCode);
253                break;
254            case TCKind._tk_native:
255            case TCKind._tk_alias:
256            case TCKind._tk_void:
257            case TCKind._tk_Principal:
258            case TCKind._tk_abstract_interface:
259                returnValue.type(typeCode);
260                break;
261            case TCKind._tk_null:
262                // Any is already initialized to null
263                break;
264            case TCKind._tk_longdouble:
265                // Unspecified for Java
266                throw wrapper.tkLongDoubleNotSupported() ;
267            default:
268                throw wrapper.typecodeNotSupported() ;
269        }
270        return returnValue;
271    }
272/*
273    static Any setTypeOfAny(TypeCode typeCode, Any value) {
274        if (value != null) {
275            value.read_value(value.create_input_stream(), typeCode);
276        }
277        return value;
278    }
279*/
280    static Any copy(Any inAny, ORB orb) {
281        return new AnyImpl(orb, inAny);
282    }
283
284/*
285    static Any copy(Any inAny, ORB orb) {
286        Any outAny = null;
287        if (inAny != null && orb != null) {
288            outAny = orb.create_any();
289            outAny.read_value(inAny.create_input_stream(), inAny.type());
290            // isInitialized is set to true
291        }
292        return outAny;
293    }
294*/
295
296    static DynAny convertToNative(DynAny dynAny, ORB orb) {
297        if (dynAny instanceof DynAnyImpl) {
298            return dynAny;
299        } else {
300            // if copy flag wasn't true we would be using our DynAny with
301            // a foreign Any in it.
302            try {
303                return createMostDerivedDynAny(dynAny.to_any(), orb, true);
304            } catch (InconsistentTypeCode ictc) {
305                return null;
306            }
307        }
308    }
309
310    static boolean isInitialized(Any any) {
311        // Returning simply the value of Any.isInitialized() is not enough.
312        // The DynAny spec says that Anys containing null strings do not contain
313        // a "legal value" (see ptc 99-10-07, 9.2.3.3)
314        boolean isInitialized = ((AnyImpl)any).isInitialized();
315        switch (any.type().kind().value()) {
316            case TCKind._tk_string:
317                return (isInitialized && (any.extract_string() != null));
318            case TCKind._tk_wstring:
319                return (isInitialized && (any.extract_wstring() != null));
320        }
321        return isInitialized;
322    }
323
324    // This is a convenient method to reset the current component to where it was
325    // before we changed it. See DynAnyConstructedImpl.equal for use.
326    static boolean set_current_component(DynAny dynAny, DynAny currentComponent) {
327        if (currentComponent != null) {
328            try {
329                dynAny.rewind();
330                do {
331                    if (dynAny.current_component() == currentComponent)
332                        return true;
333                } while (dynAny.next());
334            } catch (TypeMismatch tm) { /* impossible */ }
335        }
336        return false;
337    }
338}
339