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