1. /*
  2. * @(#)DynAnyComplexImpl.java 1.10 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.TypeCode;
  9. import org.omg.CORBA.TCKind;
  10. import org.omg.CORBA.Any;
  11. import org.omg.CORBA.TypeCodePackage.BadKind;
  12. import org.omg.CORBA.TypeCodePackage.Bounds;
  13. import org.omg.CORBA.portable.InputStream;
  14. import org.omg.DynamicAny.*;
  15. import org.omg.DynamicAny.DynAnyPackage.TypeMismatch;
  16. import org.omg.DynamicAny.DynAnyPackage.InvalidValue;
  17. import org.omg.DynamicAny.DynAnyFactoryPackage.InconsistentTypeCode;
  18. import com.sun.corba.se.spi.orb.ORB ;
  19. import com.sun.corba.se.spi.logging.CORBALogDomains ;
  20. import com.sun.corba.se.impl.logging.ORBUtilSystemException ;
  21. abstract class DynAnyComplexImpl extends DynAnyConstructedImpl
  22. {
  23. //
  24. // Instance variables
  25. //
  26. String[] names = null;
  27. // Instance variables components and names above are kept in sync
  28. // with these two arrays at all times.
  29. NameValuePair[] nameValuePairs = null;
  30. NameDynAnyPair[] nameDynAnyPairs = null;
  31. //
  32. // Constructors
  33. //
  34. private DynAnyComplexImpl() {
  35. this(null, (Any)null, false);
  36. }
  37. protected DynAnyComplexImpl(ORB orb, Any any, boolean copyValue) {
  38. // We can be sure that typeCode is of kind tk_struct
  39. super(orb, any, copyValue);
  40. // Initialize components lazily, on demand.
  41. // This is an optimization in case the user is only interested in storing Anys.
  42. }
  43. protected DynAnyComplexImpl(ORB orb, TypeCode typeCode) {
  44. // We can be sure that typeCode is of kind tk_struct
  45. super(orb, typeCode);
  46. // For DynAnyComplex, the operation sets the current position to -1
  47. // for empty exceptions and to zero for all other TypeCodes.
  48. // The members (if any) are (recursively) initialized to their default values.
  49. index = 0;
  50. }
  51. //
  52. // DynAny interface methods
  53. //
  54. // _REVISIT_ Overridden to provide more efficient copying.
  55. // Copies all the internal representations which is faster than reconstructing them.
  56. /*
  57. public org.omg.DynamicAny.DynAny copy() {
  58. if (status == STATUS_DESTROYED) {
  59. throw new OBJECT_NOT_EXIST();
  60. }
  61. DynAnyComplexImpl returnValue = null;
  62. if ((representations & REPRESENTATION_ANY) != 0) {
  63. // The flag "true" indicates copying the Any value
  64. returnValue = (DynAnyComplexImpl)DynAnyUtil.createMostDerivedDynAny(any, orb, true);
  65. }
  66. if ((representations & REPRESENTATION_COMPONENTS) != 0) {
  67. }
  68. return returnValue;
  69. }
  70. */
  71. //
  72. // Complex methods
  73. //
  74. public String current_member_name ()
  75. throws org.omg.DynamicAny.DynAnyPackage.TypeMismatch,
  76. org.omg.DynamicAny.DynAnyPackage.InvalidValue
  77. {
  78. if (status == STATUS_DESTROYED) {
  79. throw wrapper.dynAnyDestroyed() ;
  80. }
  81. if( ! checkInitComponents() || index < 0 || index >= names.length) {
  82. throw new InvalidValue();
  83. }
  84. return names[index];
  85. }
  86. public TCKind current_member_kind ()
  87. throws org.omg.DynamicAny.DynAnyPackage.TypeMismatch,
  88. org.omg.DynamicAny.DynAnyPackage.InvalidValue
  89. {
  90. if (status == STATUS_DESTROYED) {
  91. throw wrapper.dynAnyDestroyed() ;
  92. }
  93. if( ! checkInitComponents() || index < 0 || index >= components.length) {
  94. throw new InvalidValue();
  95. }
  96. return components[index].type().kind();
  97. }
  98. // Creates references to the parameter instead of copying it.
  99. public void set_members (org.omg.DynamicAny.NameValuePair[] value)
  100. throws org.omg.DynamicAny.DynAnyPackage.TypeMismatch,
  101. org.omg.DynamicAny.DynAnyPackage.InvalidValue
  102. {
  103. if (status == STATUS_DESTROYED) {
  104. throw wrapper.dynAnyDestroyed() ;
  105. }
  106. if (value == null || value.length == 0) {
  107. clearData();
  108. return;
  109. }
  110. Any memberAny;
  111. DynAny memberDynAny = null;
  112. String memberName;
  113. // We know that this is of kind tk_struct
  114. TypeCode expectedTypeCode = any.type();
  115. int expectedMemberCount = 0;
  116. try {
  117. expectedMemberCount = expectedTypeCode.member_count();
  118. } catch (BadKind badKind) { // impossible
  119. }
  120. if (expectedMemberCount != value.length) {
  121. clearData();
  122. throw new InvalidValue();
  123. }
  124. allocComponents(value);
  125. for (int i=0; i<value.length; i++) {
  126. if (value[i] != null) {
  127. memberName = value[i].id;
  128. String expectedMemberName = null;
  129. try {
  130. expectedMemberName = expectedTypeCode.member_name(i);
  131. } catch (BadKind badKind) { // impossible
  132. } catch (Bounds bounds) { // impossible
  133. }
  134. if ( ! (expectedMemberName.equals(memberName) || memberName.equals(""))) {
  135. clearData();
  136. // _REVISIT_ More info
  137. throw new TypeMismatch();
  138. }
  139. memberAny = value[i].value;
  140. TypeCode expectedMemberType = null;
  141. try {
  142. expectedMemberType = expectedTypeCode.member_type(i);
  143. } catch (BadKind badKind) { // impossible
  144. } catch (Bounds bounds) { // impossible
  145. }
  146. if (! expectedMemberType.equal(memberAny.type())) {
  147. clearData();
  148. // _REVISIT_ More info
  149. throw new TypeMismatch();
  150. }
  151. try {
  152. // Creates the appropriate subtype without copying the Any
  153. memberDynAny = DynAnyUtil.createMostDerivedDynAny(memberAny, orb, false);
  154. } catch (InconsistentTypeCode itc) {
  155. throw new InvalidValue();
  156. }
  157. addComponent(i, memberName, memberAny, memberDynAny);
  158. } else {
  159. clearData();
  160. // _REVISIT_ More info
  161. throw new InvalidValue();
  162. }
  163. }
  164. index = (value.length == 0 ? NO_INDEX : 0);
  165. representations = REPRESENTATION_COMPONENTS;
  166. }
  167. // Creates references to the parameter instead of copying it.
  168. public void set_members_as_dyn_any (org.omg.DynamicAny.NameDynAnyPair[] value)
  169. throws org.omg.DynamicAny.DynAnyPackage.TypeMismatch,
  170. org.omg.DynamicAny.DynAnyPackage.InvalidValue
  171. {
  172. if (status == STATUS_DESTROYED) {
  173. throw wrapper.dynAnyDestroyed() ;
  174. }
  175. if (value == null || value.length == 0) {
  176. clearData();
  177. return;
  178. }
  179. Any memberAny;
  180. DynAny memberDynAny;
  181. String memberName;
  182. // We know that this is of kind tk_struct
  183. TypeCode expectedTypeCode = any.type();
  184. int expectedMemberCount = 0;
  185. try {
  186. expectedMemberCount = expectedTypeCode.member_count();
  187. } catch (BadKind badKind) { // impossible
  188. }
  189. if (expectedMemberCount != value.length) {
  190. clearData();
  191. throw new InvalidValue();
  192. }
  193. allocComponents(value);
  194. for (int i=0; i<value.length; i++) {
  195. if (value[i] != null) {
  196. memberName = value[i].id;
  197. String expectedMemberName = null;
  198. try {
  199. expectedMemberName = expectedTypeCode.member_name(i);
  200. } catch (BadKind badKind) { // impossible
  201. } catch (Bounds bounds) { // impossible
  202. }
  203. if ( ! (expectedMemberName.equals(memberName) || memberName.equals(""))) {
  204. clearData();
  205. // _REVISIT_ More info
  206. throw new TypeMismatch();
  207. }
  208. memberDynAny = value[i].value;
  209. memberAny = getAny(memberDynAny);
  210. TypeCode expectedMemberType = null;
  211. try {
  212. expectedMemberType = expectedTypeCode.member_type(i);
  213. } catch (BadKind badKind) { // impossible
  214. } catch (Bounds bounds) { // impossible
  215. }
  216. if (! expectedMemberType.equal(memberAny.type())) {
  217. clearData();
  218. // _REVISIT_ More info
  219. throw new TypeMismatch();
  220. }
  221. addComponent(i, memberName, memberAny, memberDynAny);
  222. } else {
  223. clearData();
  224. // _REVISIT_ More info
  225. throw new InvalidValue();
  226. }
  227. }
  228. index = (value.length == 0 ? NO_INDEX : 0);
  229. representations = REPRESENTATION_COMPONENTS;
  230. }
  231. //
  232. // Utility methods
  233. //
  234. private void allocComponents(int length) {
  235. components = new DynAny[length];
  236. names = new String[length];
  237. nameValuePairs = new NameValuePair[length];
  238. nameDynAnyPairs = new NameDynAnyPair[length];
  239. for (int i=0; i<length; i++) {
  240. nameValuePairs[i] = new NameValuePair();
  241. nameDynAnyPairs[i] = new NameDynAnyPair();
  242. }
  243. }
  244. private void allocComponents(org.omg.DynamicAny.NameValuePair[] value) {
  245. components = new DynAny[value.length];
  246. names = new String[value.length];
  247. nameValuePairs = value;
  248. nameDynAnyPairs = new NameDynAnyPair[value.length];
  249. for (int i=0; i<value.length; i++) {
  250. nameDynAnyPairs[i] = new NameDynAnyPair();
  251. }
  252. }
  253. private void allocComponents(org.omg.DynamicAny.NameDynAnyPair[] value) {
  254. components = new DynAny[value.length];
  255. names = new String[value.length];
  256. nameValuePairs = new NameValuePair[value.length];
  257. for (int i=0; i<value.length; i++) {
  258. nameValuePairs[i] = new NameValuePair();
  259. }
  260. nameDynAnyPairs = value;
  261. }
  262. private void addComponent(int i, String memberName, Any memberAny, DynAny memberDynAny) {
  263. components[i] = memberDynAny;
  264. names[i] = (memberName != null ? memberName : "");
  265. nameValuePairs[i].id = memberName;
  266. nameValuePairs[i].value = memberAny;
  267. nameDynAnyPairs[i].id = memberName;
  268. nameDynAnyPairs[i].value = memberDynAny;
  269. if (memberDynAny instanceof DynAnyImpl)
  270. ((DynAnyImpl)memberDynAny).setStatus(STATUS_UNDESTROYABLE);
  271. }
  272. // Initializes components, names, nameValuePairs and nameDynAnyPairs representation
  273. // from the Any representation
  274. protected boolean initializeComponentsFromAny() {
  275. // This typeCode is of kind tk_struct.
  276. TypeCode typeCode = any.type();
  277. TypeCode memberType = null;
  278. Any memberAny;
  279. DynAny memberDynAny = null;
  280. String memberName = null;
  281. int length = 0;
  282. try {
  283. length = typeCode.member_count();
  284. } catch (BadKind badKind) { // impossible
  285. }
  286. InputStream input = any.create_input_stream();
  287. allocComponents(length);
  288. for (int i=0; i<length; i++) {
  289. try {
  290. memberName = typeCode.member_name(i);
  291. memberType = typeCode.member_type(i);
  292. } catch (BadKind badKind) { // impossible
  293. } catch (Bounds bounds) { // impossible
  294. }
  295. memberAny = DynAnyUtil.extractAnyFromStream(memberType, input, orb);
  296. try {
  297. // Creates the appropriate subtype without copying the Any
  298. memberDynAny = DynAnyUtil.createMostDerivedDynAny(memberAny, orb, false);
  299. // _DEBUG_
  300. //System.out.println("Created DynAny for " + memberName +
  301. // ", type " + memberType.kind().value());
  302. } catch (InconsistentTypeCode itc) { // impossible
  303. }
  304. addComponent(i, memberName, memberAny, memberDynAny);
  305. }
  306. return true;
  307. }
  308. // Initializes components, names, nameValuePairs and nameDynAnyPairs representation
  309. // from the internal TypeCode information with default values
  310. // This is not done recursively, only one level.
  311. // More levels are initialized lazily, on demand.
  312. protected boolean initializeComponentsFromTypeCode() {
  313. // This typeCode is of kind tk_struct.
  314. TypeCode typeCode = any.type();
  315. TypeCode memberType = null;
  316. Any memberAny;
  317. DynAny memberDynAny = null;
  318. String memberName;
  319. int length = 0;
  320. try {
  321. length = typeCode.member_count();
  322. } catch (BadKind badKind) { // impossible
  323. }
  324. allocComponents(length);
  325. for (int i=0; i<length; i++) {
  326. memberName = null;
  327. try {
  328. memberName = typeCode.member_name(i);
  329. memberType = typeCode.member_type(i);
  330. } catch (BadKind badKind) { // impossible
  331. } catch (Bounds bounds) { // impossible
  332. }
  333. try {
  334. memberDynAny = DynAnyUtil.createMostDerivedDynAny(memberType, orb);
  335. // _DEBUG_
  336. //System.out.println("Created DynAny for " + memberName +
  337. // ", type " + memberType.kind().value());
  338. /*
  339. if (memberDynAny instanceof DynAnyConstructedImpl) {
  340. if ( ! ((DynAnyConstructedImpl)memberDynAny).isRecursive()) {
  341. // This is the recursive part
  342. ((DynAnyConstructedImpl)memberDynAny).initializeComponentsFromTypeCode();
  343. }
  344. } // Other implementations have their own way of dealing with implementing the spec.
  345. */
  346. } catch (InconsistentTypeCode itc) { // impossible
  347. }
  348. // get a hold of the default initialized Any without copying
  349. memberAny = getAny(memberDynAny);
  350. addComponent(i, memberName, memberAny, memberDynAny);
  351. }
  352. return true;
  353. }
  354. // It is probably right not to destroy the released component DynAnys.
  355. // Some other DynAny or a user variable might still hold onto them
  356. // and if not then the garbage collector will take care of it.
  357. protected void clearData() {
  358. super.clearData();
  359. names = null;
  360. nameValuePairs = null;
  361. nameDynAnyPairs = null;
  362. }
  363. }