001: /*
002: * Copyright 2000-2003 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: package com.sun.corba.se.impl.dynamicany;
027:
028: import org.omg.CORBA.Any;
029: import org.omg.CORBA.TypeCode;
030: import org.omg.CORBA.TCKind;
031: import org.omg.CORBA.portable.OutputStream; //import org.omg.CORBA.ORBPackage.*;
032: import org.omg.CORBA.TypeCodePackage.BadKind;
033: import org.omg.CORBA.TypeCodePackage.Bounds;
034: import org.omg.CORBA.portable.InputStream;
035: import org.omg.DynamicAny.*;
036: import org.omg.DynamicAny.DynAnyPackage.TypeMismatch;
037: import org.omg.DynamicAny.DynAnyFactoryPackage.InconsistentTypeCode;
038: import java.math.BigDecimal;
039: import com.sun.corba.se.impl.corba.AnyImpl;
040:
041: import com.sun.corba.se.spi.orb.ORB;
042: import com.sun.corba.se.spi.logging.CORBALogDomains;
043: import com.sun.corba.se.impl.logging.ORBUtilSystemException;
044:
045: public class DynAnyUtil {
046: static boolean isConsistentType(TypeCode typeCode) {
047: int kind = typeCode.kind().value();
048: return (kind != TCKind._tk_Principal
049: && kind != TCKind._tk_native && kind != TCKind._tk_abstract_interface);
050: }
051:
052: static boolean isConstructedDynAny(DynAny dynAny) {
053: // DynFixed is constructed but not a subclass of DynAnyConstructedImpl
054: //return (dynAny instanceof DynAnyConstructedImpl);
055: int kind = dynAny.type().kind().value();
056: return (kind == TCKind._tk_sequence
057: || kind == TCKind._tk_struct
058: || kind == TCKind._tk_array || kind == TCKind._tk_union
059: || kind == TCKind._tk_enum || kind == TCKind._tk_fixed
060: || kind == TCKind._tk_value || kind == TCKind._tk_value_box);
061: }
062:
063: static DynAny createMostDerivedDynAny(Any any, ORB orb,
064: boolean copyValue)
065: throws org.omg.DynamicAny.DynAnyFactoryPackage.InconsistentTypeCode {
066: if (any == null || !DynAnyUtil.isConsistentType(any.type()))
067: throw new org.omg.DynamicAny.DynAnyFactoryPackage.InconsistentTypeCode();
068:
069: switch (any.type().kind().value()) {
070: case TCKind._tk_sequence:
071: return new DynSequenceImpl(orb, any, copyValue);
072: case TCKind._tk_struct:
073: return new DynStructImpl(orb, any, copyValue);
074: case TCKind._tk_array:
075: return new DynArrayImpl(orb, any, copyValue);
076: case TCKind._tk_union:
077: return new DynUnionImpl(orb, any, copyValue);
078: case TCKind._tk_enum:
079: return new DynEnumImpl(orb, any, copyValue);
080: case TCKind._tk_fixed:
081: return new DynFixedImpl(orb, any, copyValue);
082: case TCKind._tk_value:
083: return new DynValueImpl(orb, any, copyValue);
084: case TCKind._tk_value_box:
085: return new DynValueBoxImpl(orb, any, copyValue);
086: default:
087: return new DynAnyBasicImpl(orb, any, copyValue);
088: }
089: }
090:
091: static DynAny createMostDerivedDynAny(TypeCode typeCode, ORB orb)
092: throws org.omg.DynamicAny.DynAnyFactoryPackage.InconsistentTypeCode {
093: if (typeCode == null || !DynAnyUtil.isConsistentType(typeCode))
094: throw new org.omg.DynamicAny.DynAnyFactoryPackage.InconsistentTypeCode();
095:
096: switch (typeCode.kind().value()) {
097: case TCKind._tk_sequence:
098: return new DynSequenceImpl(orb, typeCode);
099: case TCKind._tk_struct:
100: return new DynStructImpl(orb, typeCode);
101: case TCKind._tk_array:
102: return new DynArrayImpl(orb, typeCode);
103: case TCKind._tk_union:
104: return new DynUnionImpl(orb, typeCode);
105: case TCKind._tk_enum:
106: return new DynEnumImpl(orb, typeCode);
107: case TCKind._tk_fixed:
108: return new DynFixedImpl(orb, typeCode);
109: case TCKind._tk_value:
110: return new DynValueImpl(orb, typeCode);
111: case TCKind._tk_value_box:
112: return new DynValueBoxImpl(orb, typeCode);
113: default:
114: return new DynAnyBasicImpl(orb, typeCode);
115: }
116: }
117:
118: // Extracts a member value according to the given TypeCode from the given complex Any
119: // (at the Anys current internal stream position, consuming the anys stream on the way)
120: // and returns it wrapped into a new Any
121: /*
122: static Any extractAnyFromAny(TypeCode memberType, Any any, ORB orb) {
123: // Moved this functionality into AnyImpl because it is needed for Any.equal()
124: return ((AnyImpl)any).extractAny(memberType, orb);
125: }
126: */
127:
128: // Extracts a member value according to the given TypeCode from the given complex Any
129: // (at the Anys current internal stream position, consuming the anys stream on the way)
130: // and returns it wrapped into a new Any
131: static Any extractAnyFromStream(TypeCode memberType,
132: InputStream input, ORB orb) {
133: return AnyImpl.extractAnyFromStream(memberType, input, orb);
134: }
135:
136: // Creates a default Any of the given type.
137: static Any createDefaultAnyOfType(TypeCode typeCode, ORB orb) {
138: ORBUtilSystemException wrapper = ORBUtilSystemException.get(
139: orb, CORBALogDomains.RPC_PRESENTATION);
140:
141: Any returnValue = orb.create_any();
142: // The spec for DynAny differs from Any on initialization via type code:
143: // - false for boolean
144: // - zero for numeric types
145: // - zero for types octet, char, and wchar
146: // - the empty string for string and wstring
147: // - nil for object references
148: // - a type code with a TCKind value of tk_null for type codes
149: // - for Any values, an Any containing a type code with a TCKind value of tk_null
150: // type and no value
151: switch (typeCode.kind().value()) {
152: case TCKind._tk_boolean:
153: // false for boolean
154: returnValue.insert_boolean(false);
155: break;
156: case TCKind._tk_short:
157: // zero for numeric types
158: returnValue.insert_short((short) 0);
159: break;
160: case TCKind._tk_ushort:
161: // zero for numeric types
162: returnValue.insert_ushort((short) 0);
163: break;
164: case TCKind._tk_long:
165: // zero for numeric types
166: returnValue.insert_long(0);
167: break;
168: case TCKind._tk_ulong:
169: // zero for numeric types
170: returnValue.insert_ulong(0);
171: break;
172: case TCKind._tk_longlong:
173: // zero for numeric types
174: returnValue.insert_longlong((long) 0);
175: break;
176: case TCKind._tk_ulonglong:
177: // zero for numeric types
178: returnValue.insert_ulonglong((long) 0);
179: break;
180: case TCKind._tk_float:
181: // zero for numeric types
182: returnValue.insert_float((float) 0.0);
183: break;
184: case TCKind._tk_double:
185: // zero for numeric types
186: returnValue.insert_double((double) 0.0);
187: break;
188: case TCKind._tk_octet:
189: // zero for types octet, char, and wchar
190: returnValue.insert_octet((byte) 0);
191: break;
192: case TCKind._tk_char:
193: // zero for types octet, char, and wchar
194: returnValue.insert_char((char) 0);
195: break;
196: case TCKind._tk_wchar:
197: // zero for types octet, char, and wchar
198: returnValue.insert_wchar((char) 0);
199: break;
200: case TCKind._tk_string:
201: // the empty string for string and wstring
202: // Make sure that type code for bounded strings gets respected
203: returnValue.type(typeCode);
204: // Doesn't erase the type of bounded string
205: returnValue.insert_string("");
206: break;
207: case TCKind._tk_wstring:
208: // the empty string for string and wstring
209: // Make sure that type code for bounded strings gets respected
210: returnValue.type(typeCode);
211: // Doesn't erase the type of bounded string
212: returnValue.insert_wstring("");
213: break;
214: case TCKind._tk_objref:
215: // nil for object references
216: returnValue.insert_Object(null);
217: break;
218: case TCKind._tk_TypeCode:
219: // a type code with a TCKind value of tk_null for type codes
220: // We can reuse the type code that's already in the any.
221: returnValue.insert_TypeCode(returnValue.type());
222: break;
223: case TCKind._tk_any:
224: // for Any values, an Any containing a type code with a TCKind value
225: // of tk_null type and no value.
226: // This is exactly what the default AnyImpl constructor provides.
227: // _REVISIT_ Note that this inner Any is considered uninitialized.
228: returnValue.insert_any(orb.create_any());
229: break;
230: case TCKind._tk_struct:
231: case TCKind._tk_union:
232: case TCKind._tk_enum:
233: case TCKind._tk_sequence:
234: case TCKind._tk_array:
235: case TCKind._tk_except:
236: case TCKind._tk_value:
237: case TCKind._tk_value_box:
238: // There are no default value for complex types since there is no
239: // concept of a hierarchy of Anys. Only DynAnys can be arrange in
240: // a hierarchy to mirror the TypeCode hierarchy.
241: // See DynAnyConstructedImpl.initializeComponentsFromTypeCode()
242: // on how this DynAny hierarchy is created from TypeCodes.
243: returnValue.type(typeCode);
244: break;
245: case TCKind._tk_fixed:
246: returnValue.insert_fixed(new BigDecimal("0.0"), typeCode);
247: break;
248: case TCKind._tk_native:
249: case TCKind._tk_alias:
250: case TCKind._tk_void:
251: case TCKind._tk_Principal:
252: case TCKind._tk_abstract_interface:
253: returnValue.type(typeCode);
254: break;
255: case TCKind._tk_null:
256: // Any is already initialized to null
257: break;
258: case TCKind._tk_longdouble:
259: // Unspecified for Java
260: throw wrapper.tkLongDoubleNotSupported();
261: default:
262: throw wrapper.typecodeNotSupported();
263: }
264: return returnValue;
265: }
266:
267: /*
268: static Any setTypeOfAny(TypeCode typeCode, Any value) {
269: if (value != null) {
270: value.read_value(value.create_input_stream(), typeCode);
271: }
272: return value;
273: }
274: */
275: static Any copy(Any inAny, ORB orb) {
276: return new AnyImpl(orb, inAny);
277: }
278:
279: /*
280: static Any copy(Any inAny, ORB orb) {
281: Any outAny = null;
282: if (inAny != null && orb != null) {
283: outAny = orb.create_any();
284: outAny.read_value(inAny.create_input_stream(), inAny.type());
285: // isInitialized is set to true
286: }
287: return outAny;
288: }
289: */
290:
291: static DynAny convertToNative(DynAny dynAny, ORB orb) {
292: if (dynAny instanceof DynAnyImpl) {
293: return dynAny;
294: } else {
295: // if copy flag wasn't true we would be using our DynAny with
296: // a foreign Any in it.
297: try {
298: return createMostDerivedDynAny(dynAny.to_any(), orb,
299: true);
300: } catch (InconsistentTypeCode ictc) {
301: return null;
302: }
303: }
304: }
305:
306: static boolean isInitialized(Any any) {
307: // Returning simply the value of Any.isInitialized() is not enough.
308: // The DynAny spec says that Anys containing null strings do not contain
309: // a "legal value" (see ptc 99-10-07, 9.2.3.3)
310: boolean isInitialized = ((AnyImpl) any).isInitialized();
311: switch (any.type().kind().value()) {
312: case TCKind._tk_string:
313: return (isInitialized && (any.extract_string() != null));
314: case TCKind._tk_wstring:
315: return (isInitialized && (any.extract_wstring() != null));
316: }
317: return isInitialized;
318: }
319:
320: // This is a convenient method to reset the current component to where it was
321: // before we changed it. See DynAnyConstructedImpl.equal for use.
322: static boolean set_current_component(DynAny dynAny,
323: DynAny currentComponent) {
324: if (currentComponent != null) {
325: try {
326: dynAny.rewind();
327: do {
328: if (dynAny.current_component() == currentComponent)
329: return true;
330: } while (dynAny.next());
331: } catch (TypeMismatch tm) { /* impossible */
332: }
333: }
334: return false;
335: }
336: }
|