001: /*
002: * Copyright 2000-2003 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package com.sun.corba.se.impl.dynamicany;
027:
028: import org.omg.CORBA.TypeCode;
029: import org.omg.CORBA.TCKind;
030: import org.omg.CORBA.Any;
031: import org.omg.CORBA.TypeCodePackage.BadKind;
032: import org.omg.CORBA.TypeCodePackage.Bounds;
033: import org.omg.CORBA.portable.InputStream;
034: import org.omg.DynamicAny.*;
035: import org.omg.DynamicAny.DynAnyPackage.TypeMismatch;
036: import org.omg.DynamicAny.DynAnyPackage.InvalidValue;
037: import org.omg.DynamicAny.DynAnyFactoryPackage.InconsistentTypeCode;
038:
039: import com.sun.corba.se.spi.orb.ORB;
040: import com.sun.corba.se.spi.logging.CORBALogDomains;
041: import com.sun.corba.se.impl.logging.ORBUtilSystemException;
042:
043: abstract class DynAnyComplexImpl extends DynAnyConstructedImpl {
044: //
045: // Instance variables
046: //
047:
048: String[] names = null;
049: // Instance variables components and names above are kept in sync
050: // with these two arrays at all times.
051: NameValuePair[] nameValuePairs = null;
052: NameDynAnyPair[] nameDynAnyPairs = null;
053:
054: //
055: // Constructors
056: //
057:
058: private DynAnyComplexImpl() {
059: this (null, (Any) null, false);
060: }
061:
062: protected DynAnyComplexImpl(ORB orb, Any any, boolean copyValue) {
063: // We can be sure that typeCode is of kind tk_struct
064: super (orb, any, copyValue);
065: // Initialize components lazily, on demand.
066: // This is an optimization in case the user is only interested in storing Anys.
067: }
068:
069: protected DynAnyComplexImpl(ORB orb, TypeCode typeCode) {
070: // We can be sure that typeCode is of kind tk_struct
071: super (orb, typeCode);
072: // For DynAnyComplex, the operation sets the current position to -1
073: // for empty exceptions and to zero for all other TypeCodes.
074: // The members (if any) are (recursively) initialized to their default values.
075: index = 0;
076: }
077:
078: //
079: // DynAny interface methods
080: //
081:
082: // _REVISIT_ Overridden to provide more efficient copying.
083: // Copies all the internal representations which is faster than reconstructing them.
084: /*
085: public org.omg.DynamicAny.DynAny copy() {
086: if (status == STATUS_DESTROYED) {
087: throw new OBJECT_NOT_EXIST();
088: }
089: DynAnyComplexImpl returnValue = null;
090: if ((representations & REPRESENTATION_ANY) != 0) {
091: // The flag "true" indicates copying the Any value
092: returnValue = (DynAnyComplexImpl)DynAnyUtil.createMostDerivedDynAny(any, orb, true);
093: }
094: if ((representations & REPRESENTATION_COMPONENTS) != 0) {
095: }
096: return returnValue;
097: }
098: */
099:
100: //
101: // Complex methods
102: //
103: public String current_member_name()
104: throws org.omg.DynamicAny.DynAnyPackage.TypeMismatch,
105: org.omg.DynamicAny.DynAnyPackage.InvalidValue {
106: if (status == STATUS_DESTROYED) {
107: throw wrapper.dynAnyDestroyed();
108: }
109: if (!checkInitComponents() || index < 0
110: || index >= names.length) {
111: throw new InvalidValue();
112: }
113: return names[index];
114: }
115:
116: public TCKind current_member_kind()
117: throws org.omg.DynamicAny.DynAnyPackage.TypeMismatch,
118: org.omg.DynamicAny.DynAnyPackage.InvalidValue {
119: if (status == STATUS_DESTROYED) {
120: throw wrapper.dynAnyDestroyed();
121: }
122: if (!checkInitComponents() || index < 0
123: || index >= components.length) {
124: throw new InvalidValue();
125: }
126: return components[index].type().kind();
127: }
128:
129: // Creates references to the parameter instead of copying it.
130: public void set_members(org.omg.DynamicAny.NameValuePair[] value)
131: throws org.omg.DynamicAny.DynAnyPackage.TypeMismatch,
132: org.omg.DynamicAny.DynAnyPackage.InvalidValue {
133: if (status == STATUS_DESTROYED) {
134: throw wrapper.dynAnyDestroyed();
135: }
136: if (value == null || value.length == 0) {
137: clearData();
138: return;
139: }
140:
141: Any memberAny;
142: DynAny memberDynAny = null;
143: String memberName;
144: // We know that this is of kind tk_struct
145: TypeCode expectedTypeCode = any.type();
146:
147: int expectedMemberCount = 0;
148: try {
149: expectedMemberCount = expectedTypeCode.member_count();
150: } catch (BadKind badKind) { // impossible
151: }
152: if (expectedMemberCount != value.length) {
153: clearData();
154: throw new InvalidValue();
155: }
156:
157: allocComponents(value);
158:
159: for (int i = 0; i < value.length; i++) {
160: if (value[i] != null) {
161: memberName = value[i].id;
162: String expectedMemberName = null;
163: try {
164: expectedMemberName = expectedTypeCode
165: .member_name(i);
166: } catch (BadKind badKind) { // impossible
167: } catch (Bounds bounds) { // impossible
168: }
169: if (!(expectedMemberName.equals(memberName) || memberName
170: .equals(""))) {
171: clearData();
172: // _REVISIT_ More info
173: throw new TypeMismatch();
174: }
175: memberAny = value[i].value;
176: TypeCode expectedMemberType = null;
177: try {
178: expectedMemberType = expectedTypeCode
179: .member_type(i);
180: } catch (BadKind badKind) { // impossible
181: } catch (Bounds bounds) { // impossible
182: }
183: if (!expectedMemberType.equal(memberAny.type())) {
184: clearData();
185: // _REVISIT_ More info
186: throw new TypeMismatch();
187: }
188: try {
189: // Creates the appropriate subtype without copying the Any
190: memberDynAny = DynAnyUtil.createMostDerivedDynAny(
191: memberAny, orb, false);
192: } catch (InconsistentTypeCode itc) {
193: throw new InvalidValue();
194: }
195: addComponent(i, memberName, memberAny, memberDynAny);
196: } else {
197: clearData();
198: // _REVISIT_ More info
199: throw new InvalidValue();
200: }
201: }
202: index = (value.length == 0 ? NO_INDEX : 0);
203: representations = REPRESENTATION_COMPONENTS;
204: }
205:
206: // Creates references to the parameter instead of copying it.
207: public void set_members_as_dyn_any(
208: org.omg.DynamicAny.NameDynAnyPair[] value)
209: throws org.omg.DynamicAny.DynAnyPackage.TypeMismatch,
210: org.omg.DynamicAny.DynAnyPackage.InvalidValue {
211: if (status == STATUS_DESTROYED) {
212: throw wrapper.dynAnyDestroyed();
213: }
214: if (value == null || value.length == 0) {
215: clearData();
216: return;
217: }
218:
219: Any memberAny;
220: DynAny memberDynAny;
221: String memberName;
222: // We know that this is of kind tk_struct
223: TypeCode expectedTypeCode = any.type();
224:
225: int expectedMemberCount = 0;
226: try {
227: expectedMemberCount = expectedTypeCode.member_count();
228: } catch (BadKind badKind) { // impossible
229: }
230: if (expectedMemberCount != value.length) {
231: clearData();
232: throw new InvalidValue();
233: }
234:
235: allocComponents(value);
236:
237: for (int i = 0; i < value.length; i++) {
238: if (value[i] != null) {
239: memberName = value[i].id;
240: String expectedMemberName = null;
241: try {
242: expectedMemberName = expectedTypeCode
243: .member_name(i);
244: } catch (BadKind badKind) { // impossible
245: } catch (Bounds bounds) { // impossible
246: }
247: if (!(expectedMemberName.equals(memberName) || memberName
248: .equals(""))) {
249: clearData();
250: // _REVISIT_ More info
251: throw new TypeMismatch();
252: }
253: memberDynAny = value[i].value;
254: memberAny = getAny(memberDynAny);
255: TypeCode expectedMemberType = null;
256: try {
257: expectedMemberType = expectedTypeCode
258: .member_type(i);
259: } catch (BadKind badKind) { // impossible
260: } catch (Bounds bounds) { // impossible
261: }
262: if (!expectedMemberType.equal(memberAny.type())) {
263: clearData();
264: // _REVISIT_ More info
265: throw new TypeMismatch();
266: }
267:
268: addComponent(i, memberName, memberAny, memberDynAny);
269: } else {
270: clearData();
271: // _REVISIT_ More info
272: throw new InvalidValue();
273: }
274: }
275: index = (value.length == 0 ? NO_INDEX : 0);
276: representations = REPRESENTATION_COMPONENTS;
277: }
278:
279: //
280: // Utility methods
281: //
282:
283: private void allocComponents(int length) {
284: components = new DynAny[length];
285: names = new String[length];
286: nameValuePairs = new NameValuePair[length];
287: nameDynAnyPairs = new NameDynAnyPair[length];
288: for (int i = 0; i < length; i++) {
289: nameValuePairs[i] = new NameValuePair();
290: nameDynAnyPairs[i] = new NameDynAnyPair();
291: }
292: }
293:
294: private void allocComponents(
295: org.omg.DynamicAny.NameValuePair[] value) {
296: components = new DynAny[value.length];
297: names = new String[value.length];
298: nameValuePairs = value;
299: nameDynAnyPairs = new NameDynAnyPair[value.length];
300: for (int i = 0; i < value.length; i++) {
301: nameDynAnyPairs[i] = new NameDynAnyPair();
302: }
303: }
304:
305: private void allocComponents(
306: org.omg.DynamicAny.NameDynAnyPair[] value) {
307: components = new DynAny[value.length];
308: names = new String[value.length];
309: nameValuePairs = new NameValuePair[value.length];
310: for (int i = 0; i < value.length; i++) {
311: nameValuePairs[i] = new NameValuePair();
312: }
313: nameDynAnyPairs = value;
314: }
315:
316: private void addComponent(int i, String memberName, Any memberAny,
317: DynAny memberDynAny) {
318: components[i] = memberDynAny;
319: names[i] = (memberName != null ? memberName : "");
320: nameValuePairs[i].id = memberName;
321: nameValuePairs[i].value = memberAny;
322: nameDynAnyPairs[i].id = memberName;
323: nameDynAnyPairs[i].value = memberDynAny;
324: if (memberDynAny instanceof DynAnyImpl)
325: ((DynAnyImpl) memberDynAny).setStatus(STATUS_UNDESTROYABLE);
326: }
327:
328: // Initializes components, names, nameValuePairs and nameDynAnyPairs representation
329: // from the Any representation
330: protected boolean initializeComponentsFromAny() {
331: // This typeCode is of kind tk_struct.
332: TypeCode typeCode = any.type();
333: TypeCode memberType = null;
334: Any memberAny;
335: DynAny memberDynAny = null;
336: String memberName = null;
337: int length = 0;
338:
339: try {
340: length = typeCode.member_count();
341: } catch (BadKind badKind) { // impossible
342: }
343:
344: InputStream input = any.create_input_stream();
345:
346: allocComponents(length);
347:
348: for (int i = 0; i < length; i++) {
349: try {
350: memberName = typeCode.member_name(i);
351: memberType = typeCode.member_type(i);
352: } catch (BadKind badKind) { // impossible
353: } catch (Bounds bounds) { // impossible
354: }
355: memberAny = DynAnyUtil.extractAnyFromStream(memberType,
356: input, orb);
357: try {
358: // Creates the appropriate subtype without copying the Any
359: memberDynAny = DynAnyUtil.createMostDerivedDynAny(
360: memberAny, orb, false);
361: // _DEBUG_
362: //System.out.println("Created DynAny for " + memberName +
363: // ", type " + memberType.kind().value());
364: } catch (InconsistentTypeCode itc) { // impossible
365: }
366: addComponent(i, memberName, memberAny, memberDynAny);
367: }
368: return true;
369: }
370:
371: // Initializes components, names, nameValuePairs and nameDynAnyPairs representation
372: // from the internal TypeCode information with default values
373: // This is not done recursively, only one level.
374: // More levels are initialized lazily, on demand.
375: protected boolean initializeComponentsFromTypeCode() {
376: // This typeCode is of kind tk_struct.
377: TypeCode typeCode = any.type();
378: TypeCode memberType = null;
379: Any memberAny;
380: DynAny memberDynAny = null;
381: String memberName;
382: int length = 0;
383:
384: try {
385: length = typeCode.member_count();
386: } catch (BadKind badKind) { // impossible
387: }
388:
389: allocComponents(length);
390:
391: for (int i = 0; i < length; i++) {
392: memberName = null;
393: try {
394: memberName = typeCode.member_name(i);
395: memberType = typeCode.member_type(i);
396: } catch (BadKind badKind) { // impossible
397: } catch (Bounds bounds) { // impossible
398: }
399: try {
400: memberDynAny = DynAnyUtil.createMostDerivedDynAny(
401: memberType, orb);
402: // _DEBUG_
403: //System.out.println("Created DynAny for " + memberName +
404: // ", type " + memberType.kind().value());
405: /*
406: if (memberDynAny instanceof DynAnyConstructedImpl) {
407: if ( ! ((DynAnyConstructedImpl)memberDynAny).isRecursive()) {
408: // This is the recursive part
409: ((DynAnyConstructedImpl)memberDynAny).initializeComponentsFromTypeCode();
410: }
411: } // Other implementations have their own way of dealing with implementing the spec.
412: */
413: } catch (InconsistentTypeCode itc) { // impossible
414: }
415: // get a hold of the default initialized Any without copying
416: memberAny = getAny(memberDynAny);
417: addComponent(i, memberName, memberAny, memberDynAny);
418: }
419: return true;
420: }
421:
422: // It is probably right not to destroy the released component DynAnys.
423: // Some other DynAny or a user variable might still hold onto them
424: // and if not then the garbage collector will take care of it.
425: protected void clearData() {
426: super.clearData();
427: names = null;
428: nameValuePairs = null;
429: nameDynAnyPairs = null;
430: }
431: }
|