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