/* * @(#)DynAnyConstructedImpl.java 1.9 03/12/19 * * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package com.sun.corba.se.impl.dynamicany; import org.omg.CORBA.Any; import org.omg.CORBA.TypeCode; import org.omg.CORBA.portable.OutputStream; import org.omg.DynamicAny.*; import org.omg.DynamicAny.DynAnyPackage.TypeMismatch; import org.omg.DynamicAny.DynAnyPackage.InvalidValue; import org.omg.DynamicAny.DynAnyFactoryPackage.InconsistentTypeCode; import com.sun.corba.se.impl.corba.TypeCodeImpl; // needed for recursive type codes import com.sun.corba.se.spi.orb.ORB ; import com.sun.corba.se.spi.logging.CORBALogDomains ; import com.sun.corba.se.impl.logging.ORBUtilSystemException ; abstract class DynAnyConstructedImpl extends DynAnyImpl { protected static final byte REPRESENTATION_NONE = 0; protected static final byte REPRESENTATION_TYPECODE = 1; protected static final byte REPRESENTATION_ANY = 2; protected static final byte REPRESENTATION_COMPONENTS = 4; protected static final byte RECURSIVE_UNDEF = -1; protected static final byte RECURSIVE_NO = 0; protected static final byte RECURSIVE_YES = 1; protected static final DynAny[] emptyComponents = new DynAny[0]; // // Instance variables // // Constructed DynAnys maintain an ordered collection of component DynAnys. DynAny[] components = emptyComponents; byte representations = REPRESENTATION_NONE; byte isRecursive = RECURSIVE_UNDEF; // // Constructors // private DynAnyConstructedImpl() { this(null, (Any)null, false); } protected DynAnyConstructedImpl(ORB orb, Any any, boolean copyValue) { super(orb, any, copyValue); //System.out.println(this + " constructed with any " + any); if (this.any != null) { representations = REPRESENTATION_ANY; } // set the current position to 0 if any has components, otherwise to -1. index = 0; } protected DynAnyConstructedImpl(ORB orb, TypeCode typeCode) { // assertion: typeCode has been checked to be valid for this particular subclass. // note: We don't copy TypeCodes since they are considered immutable. super(orb, typeCode); if (typeCode != null) { representations = REPRESENTATION_TYPECODE; } // set the current position to 0 if any has components, otherwise to -1. index = NO_INDEX; // _REVISIT_ Would need REPRESENTATION_TYPECODE for lazy initialization //if ( ! isRecursive()) { // initializeComponentsFromTypeCode(); //} } protected boolean isRecursive() { if (isRecursive == RECURSIVE_UNDEF) { TypeCode typeCode = any.type(); if (typeCode instanceof TypeCodeImpl) { if (((TypeCodeImpl)typeCode).is_recursive()) isRecursive = RECURSIVE_YES; else isRecursive = RECURSIVE_NO; } else { // No way to find out unless the TypeCode spec changes. isRecursive = RECURSIVE_NO; } } return (isRecursive == RECURSIVE_YES); } // // DynAny traversal methods // public org.omg.DynamicAny.DynAny current_component() throws org.omg.DynamicAny.DynAnyPackage.TypeMismatch { if (status == STATUS_DESTROYED) { throw wrapper.dynAnyDestroyed() ; } if (index == NO_INDEX) { return null; } return (checkInitComponents() ? components[index] : null); } public int component_count() { if (status == STATUS_DESTROYED) { throw wrapper.dynAnyDestroyed() ; } return (checkInitComponents() ? components.length : 0); } public boolean next() { if (status == STATUS_DESTROYED) { throw wrapper.dynAnyDestroyed() ; } if (checkInitComponents() == false) { return false; } index++; if (index >= 0 && index < components.length) { return true; } else { index = NO_INDEX; return false; } } public boolean seek(int newIndex) { if (status == STATUS_DESTROYED) { throw wrapper.dynAnyDestroyed() ; } if (newIndex < 0) { this.index = NO_INDEX; return false; } if (checkInitComponents() == false) { return false; } if (newIndex < components.length) { index = newIndex; return true; } return false; } public void rewind() { if (status == STATUS_DESTROYED) { throw wrapper.dynAnyDestroyed() ; } this.seek(0); } // // Utility methods // protected void clearData() { super.clearData(); // _REVISIT_ What about status? components = emptyComponents; index = NO_INDEX; representations = REPRESENTATION_NONE; } protected void writeAny(OutputStream out) { // If all we got is TypeCode representation (no value) // then we don't want to force creating a default value //System.out.println(this + " checkInitAny before writeAny"); checkInitAny(); super.writeAny(out); } // Makes sure that the components representation is initialized protected boolean checkInitComponents() { if ((representations & REPRESENTATION_COMPONENTS) == 0) { if ((representations & REPRESENTATION_ANY) != 0) { if (initializeComponentsFromAny()) { representations |= REPRESENTATION_COMPONENTS; } else { return false; } } else if ((representations & REPRESENTATION_TYPECODE) != 0) { if (initializeComponentsFromTypeCode()) { representations |= REPRESENTATION_COMPONENTS; } else { return false; } } } return true; } // Makes sure that the Any representation is initialized protected void checkInitAny() { if ((representations & REPRESENTATION_ANY) == 0) { //System.out.println(this + " checkInitAny: reps does not have REPRESENTATION_ANY"); if ((representations & REPRESENTATION_COMPONENTS) != 0) { //System.out.println(this + " checkInitAny: reps has REPRESENTATION_COMPONENTS"); if (initializeAnyFromComponents()) { representations |= REPRESENTATION_ANY; } } else if ((representations & REPRESENTATION_TYPECODE) != 0) { //System.out.println(this + " checkInitAny: reps has REPRESENTATION_TYPECODE"); if (representations == REPRESENTATION_TYPECODE && isRecursive()) return; if (initializeComponentsFromTypeCode()) { representations |= REPRESENTATION_COMPONENTS; } if (initializeAnyFromComponents()) { representations |= REPRESENTATION_ANY; } } } else { //System.out.println(this + " checkInitAny: reps != REPRESENTATION_ANY"); } return; } protected abstract boolean initializeComponentsFromAny(); protected abstract boolean initializeComponentsFromTypeCode(); // Collapses the whole DynAny hierarchys values into one single streamed Any protected boolean initializeAnyFromComponents() { //System.out.println(this + " initializeAnyFromComponents"); OutputStream out = any.create_output_stream(); for (int i=0; i