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