- /*
- * @(#)DynUnionImpl.java 1.6 03/01/23
- *
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
- * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- */
-
- package com.sun.corba.se.internal.DynamicAny;
-
- import org.omg.CORBA.ORB;
- import org.omg.CORBA.TypeCode;
- import org.omg.CORBA.TCKind;
- import org.omg.CORBA.Any;
- import org.omg.CORBA.NO_IMPLEMENT;
- import org.omg.CORBA.OBJECT_NOT_EXIST;
- import org.omg.CORBA.TypeCodePackage.BadKind;
- import org.omg.CORBA.TypeCodePackage.Bounds;
- import org.omg.CORBA.portable.InputStream;
- import org.omg.DynamicAny.*;
- import org.omg.DynamicAny.DynAnyPackage.TypeMismatch;
- import org.omg.DynamicAny.DynAnyPackage.InvalidValue;
- import org.omg.DynamicAny.DynAnyFactoryPackage.InconsistentTypeCode;
-
- public class DynUnionImpl extends DynAnyConstructedImpl implements DynUnion
- {
- //
- // Instance variables
- //
-
- DynAny discriminator = null;
- // index either points to the discriminator or the named member is it exists.
- // The currently active member, which is of the same type as the discriminator.
- DynAny currentMember = null;
- int currentMemberIndex = NO_INDEX;
-
- //
- // Constructors
- //
-
- private DynUnionImpl() {
- this(null, (Any)null, false);
- }
-
- protected DynUnionImpl(ORB orb, Any any, boolean copyValue) {
- // We can be sure that typeCode is of kind tk_union
- super(orb, any, copyValue);
- }
-
- protected DynUnionImpl(ORB orb, TypeCode typeCode) {
- // We can be sure that typeCode is of kind tk_union
- super(orb, typeCode);
- }
-
- protected boolean initializeComponentsFromAny() {
- try {
- InputStream input = any.create_input_stream();
- Any discriminatorAny = DynAnyUtil.extractAnyFromStream(discriminatorType(), input, orb);
- discriminator = DynAnyUtil.createMostDerivedDynAny(discriminatorAny, orb, false);
- currentMemberIndex = currentUnionMemberIndex(discriminatorAny);
- Any memberAny = DynAnyUtil.extractAnyFromStream(memberType(currentMemberIndex), input, orb);
- currentMember = DynAnyUtil.createMostDerivedDynAny(memberAny, orb, false);
- components = new DynAny[] {discriminator, currentMember};
- } catch (InconsistentTypeCode ictc) { // impossible
- }
- return true;
- }
-
- // Sets the current position to zero.
- // The discriminator value is set to a value consistent with the first named member
- // of the union. That member is activated and (recursively) initialized to its default value.
- protected boolean initializeComponentsFromTypeCode() {
- //System.out.println(this + " initializeComponentsFromTypeCode");
- try {
- // We can be sure that memberCount() > 0 according to the IDL language spec
- discriminator = DynAnyUtil.createMostDerivedDynAny(memberLabel(0), orb, false);
- index = 0;
- currentMemberIndex = 0;
- currentMember = DynAnyUtil.createMostDerivedDynAny(memberType(0), orb);
- components = new DynAny[] {discriminator, currentMember};
- } catch (InconsistentTypeCode ictc) { // impossible
- }
- return true;
- }
-
- //
- // Convenience methods
- //
-
- private TypeCode discriminatorType() {
- TypeCode discriminatorType = null;
- try {
- discriminatorType = any.type().discriminator_type();
- } catch (BadKind bad) {
- }
- return discriminatorType;
- }
-
- private int memberCount() {
- int memberCount = 0;
- try {
- memberCount = any.type().member_count();
- } catch (BadKind bad) {
- }
- return memberCount;
- }
-
- private Any memberLabel(int i) {
- Any memberLabel = null;
- try {
- memberLabel = any.type().member_label(i);
- } catch (BadKind bad) {
- } catch (Bounds bounds) {
- }
- return memberLabel;
- }
-
- private TypeCode memberType(int i) {
- TypeCode memberType = null;
- try {
- memberType = any.type().member_type(i);
- } catch (BadKind bad) {
- } catch (Bounds bounds) {
- }
- return memberType;
- }
-
- private String memberName(int i) {
- String memberName = null;
- try {
- memberName = any.type().member_name(i);
- } catch (BadKind bad) {
- } catch (Bounds bounds) {
- }
- return memberName;
- }
-
- private int defaultIndex() {
- int defaultIndex = -1;
- try {
- defaultIndex = any.type().default_index();
- } catch (BadKind bad) {
- }
- return defaultIndex;
- }
-
- private int currentUnionMemberIndex(Any discriminatorValue) {
- int memberCount = memberCount();
- Any memberLabel;
- for (int i=0; i<memberCount; i++) {
- memberLabel = memberLabel(i);
- if (memberLabel.equal(discriminatorValue)) {
- return i;
- }
- }
- if (defaultIndex() != -1) {
- return defaultIndex();
- }
- return NO_INDEX;
- }
-
- protected void clearData() {
- super.clearData();
- discriminator = null;
- // Necessary to guarantee OBJECT_NOT_EXIST in member()
- currentMember.destroy();
- currentMember = null;
- currentMemberIndex = NO_INDEX;
- }
-
- //
- // DynAny interface methods
- //
-
- // _REVISIT_ More efficient copy operation
-
- //
- // DynUnion interface methods
- //
-
- /**
- * Returns the current discriminator value.
- */
- public org.omg.DynamicAny.DynAny get_discriminator () {
- if (status == STATUS_DESTROYED) {
- throw new OBJECT_NOT_EXIST();
- }
- return (checkInitComponents() ? discriminator : null);
- }
-
- // Sets the discriminator of the DynUnion to the specified value.
- // If the TypeCode of the parameter is not equivalent
- // to the TypeCode of the unions discriminator, the operation raises TypeMismatch.
- //
- // Setting the discriminator to a value that is consistent with the currently
- // active union member does not affect the currently active member.
- // Setting the discriminator to a value that is inconsistent with the currently
- // active member deactivates the member and activates the member that is consistent
- // with the new discriminator value (if there is a member for that value)
- // by initializing the member to its default value.
- //
- // If the discriminator value indicates a non-existent union member
- // this operation sets the current position to 0
- // (has_no_active_member returns true in this case).
- // Otherwise the current position is set to 1 (has_no_active_member returns false and
- // component_count returns 2 in this case).
- public void set_discriminator (org.omg.DynamicAny.DynAny newDiscriminator)
- throws org.omg.DynamicAny.DynAnyPackage.TypeMismatch
- {
- if (status == STATUS_DESTROYED) {
- throw new OBJECT_NOT_EXIST();
- }
- if ( ! newDiscriminator.type().equal(discriminatorType())) {
- throw new TypeMismatch();
- }
- newDiscriminator = DynAnyUtil.convertToNative(newDiscriminator, orb);
- Any newDiscriminatorAny = getAny(newDiscriminator);
- int newCurrentMemberIndex = currentUnionMemberIndex(newDiscriminatorAny);
- if (newCurrentMemberIndex == NO_INDEX) {
- clearData();
- index = 0;
- } else {
- // _REVISIT_ Could possibly optimize here if we don't need to initialize components
- checkInitComponents();
- if (currentMemberIndex == NO_INDEX || newCurrentMemberIndex != currentMemberIndex) {
- clearData();
- index = 1;
- currentMemberIndex = newCurrentMemberIndex;
- try {
- currentMember = DynAnyUtil.createMostDerivedDynAny(memberType(currentMemberIndex), orb);
- } catch (InconsistentTypeCode ictc) {}
- discriminator = newDiscriminator;
- components = new DynAny[] { discriminator, currentMember };
- representations = REPRESENTATION_COMPONENTS;
- }
- }
- }
-
- // Sets the discriminator to a value that is consistent with the value
- // of the default case of a union; it sets the current position to
- // zero and causes component_count to return 2.
- // Calling set_to_default_member on a union that does not have an explicit
- // default case raises TypeMismatch.
- public void set_to_default_member ()
- throws org.omg.DynamicAny.DynAnyPackage.TypeMismatch
- {
- if (status == STATUS_DESTROYED) {
- throw new OBJECT_NOT_EXIST();
- }
- int defaultIndex = defaultIndex();
- if (defaultIndex == -1) {
- throw new TypeMismatch();
- }
- try {
- clearData();
- index = 1;
- currentMemberIndex = defaultIndex;
- currentMember = DynAnyUtil.createMostDerivedDynAny(memberType(defaultIndex), orb);
- components = new DynAny[] {discriminator, currentMember};
- Any discriminatorAny = orb.create_any();
- discriminatorAny.insert_octet((byte)0);
- discriminator = DynAnyUtil.createMostDerivedDynAny(discriminatorAny, orb, false);
- representations = REPRESENTATION_COMPONENTS;
- } catch (InconsistentTypeCode ictc) {}
- }
-
- // Sets the discriminator to a value that does not correspond
- // to any of the unions case labels.
- // It sets the current position to zero and causes component_count to return 1.
- // Calling set_to_no_active_member on a union that has an explicit default case
- // or on a union that uses the entire range of discriminator values
- // for explicit case labels raises TypeMismatch.
- public void set_to_no_active_member ()
- throws org.omg.DynamicAny.DynAnyPackage.TypeMismatch
- {
- if (status == STATUS_DESTROYED) {
- throw new OBJECT_NOT_EXIST();
- }
- // _REVISIT_ How does one check for "entire range of discriminator values"?
- if (defaultIndex() != -1) {
- throw new TypeMismatch();
- }
- checkInitComponents();
- Any discriminatorAny = getAny(discriminator);
- // erase the discriminators value so that it does not correspond
- // to any of the unions case labels
- discriminatorAny.type(discriminatorAny.type());
- index = 0;
- currentMemberIndex = NO_INDEX;
- // Necessary to guarantee OBJECT_NOT_EXIST in member()
- currentMember.destroy();
- currentMember = null;
- components[0] = discriminator;
- representations = REPRESENTATION_COMPONENTS;
- }
-
- // Returns true if the union has no active member
- // (that is, the unions value consists solely of its discriminator because the
- // discriminator has a value that is not listed as an explicit case label).
- // Calling this operation on a union that has a default case returns false.
- // Calling this operation on a union that uses the entire range of discriminator
- // values for explicit case labels returns false.
- public boolean has_no_active_member () {
- if (status == STATUS_DESTROYED) {
- throw new OBJECT_NOT_EXIST();
- }
- // _REVISIT_ How does one check for "entire range of discriminator values"?
- if (defaultIndex() != -1) {
- return false;
- }
- checkInitComponents();
- return (checkInitComponents() ? (currentMemberIndex == NO_INDEX) : false);
- }
-
- public org.omg.CORBA.TCKind discriminator_kind () {
- if (status == STATUS_DESTROYED) {
- throw new OBJECT_NOT_EXIST();
- }
- return discriminatorType().kind();
- }
-
- // Returns the currently active member.
- // If the union has no active member, the operation raises InvalidValue.
- // Note that the returned reference remains valid only for as long
- // as the currently active member does not change.
- // Using the returned reference beyond the life time
- // of the currently active member raises OBJECT_NOT_EXIST.
- public org.omg.DynamicAny.DynAny member ()
- throws org.omg.DynamicAny.DynAnyPackage.InvalidValue
- {
- if (status == STATUS_DESTROYED) {
- throw new OBJECT_NOT_EXIST();
- }
- if ( ! checkInitComponents() || currentMemberIndex == NO_INDEX)
- throw new InvalidValue();
- return currentMember;
- }
-
- // Returns the name of the currently active member.
- // If the unions TypeCode does not contain a member name for the currently active member,
- // the operation returns an empty string.
- // Calling member_name on a union without an active member raises InvalidValue.
- public String member_name ()
- throws org.omg.DynamicAny.DynAnyPackage.InvalidValue
- {
- if (status == STATUS_DESTROYED) {
- throw new OBJECT_NOT_EXIST();
- }
- if ( ! checkInitComponents() || currentMemberIndex == NO_INDEX)
- throw new InvalidValue();
- String memberName = memberName(currentMemberIndex);
- return (memberName == null ? "" : memberName);
- }
-
- // Returns the TCKind value of the TypeCode of the currently active member.
- // If the union has no active member, the operation raises InvalidValue.
- public org.omg.CORBA.TCKind member_kind ()
- throws org.omg.DynamicAny.DynAnyPackage.InvalidValue
- {
- if (status == STATUS_DESTROYED) {
- throw new OBJECT_NOT_EXIST();
- }
- if ( ! checkInitComponents() || currentMemberIndex == NO_INDEX)
- throw new InvalidValue();
- return memberType(currentMemberIndex).kind();
- }
- }