DynAnyComplexImpl.java revision 608:7e06bf1dcb09
1/*
2 * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package com.sun.corba.se.impl.dynamicany;
27
28import org.omg.CORBA.TypeCode;
29import org.omg.CORBA.TCKind;
30import org.omg.CORBA.Any;
31import org.omg.CORBA.TypeCodePackage.BadKind;
32import org.omg.CORBA.TypeCodePackage.Bounds;
33import org.omg.CORBA.portable.InputStream;
34import org.omg.DynamicAny.*;
35import org.omg.DynamicAny.DynAnyPackage.TypeMismatch;
36import org.omg.DynamicAny.DynAnyPackage.InvalidValue;
37import org.omg.DynamicAny.DynAnyFactoryPackage.InconsistentTypeCode;
38
39import com.sun.corba.se.spi.orb.ORB ;
40import com.sun.corba.se.spi.logging.CORBALogDomains ;
41import com.sun.corba.se.impl.logging.ORBUtilSystemException ;
42
43abstract class DynAnyComplexImpl extends DynAnyConstructedImpl
44{
45    //
46    // Instance variables
47    //
48
49    String[] names = null;
50    // Instance variables components and names above are kept in sync
51    // with these two arrays at all times.
52    NameValuePair[] nameValuePairs = null;
53    NameDynAnyPair[] nameDynAnyPairs = null;
54
55    //
56    // Constructors
57    //
58
59    private DynAnyComplexImpl() {
60        this(null, (Any)null, false);
61    }
62
63    protected DynAnyComplexImpl(ORB orb, Any any, boolean copyValue) {
64        // We can be sure that typeCode is of kind tk_struct
65        super(orb, any, copyValue);
66        // Initialize components lazily, on demand.
67        // This is an optimization in case the user is only interested in storing Anys.
68    }
69
70    protected DynAnyComplexImpl(ORB orb, TypeCode typeCode) {
71        // We can be sure that typeCode is of kind tk_struct
72        super(orb, typeCode);
73        // For DynAnyComplex, the operation sets the current position to -1
74        // for empty exceptions and to zero for all other TypeCodes.
75        // The members (if any) are (recursively) initialized to their default values.
76        index = 0;
77    }
78
79    //
80    // DynAny interface methods
81    //
82
83    // _REVISIT_ Overridden to provide more efficient copying.
84    // Copies all the internal representations which is faster than reconstructing them.
85/*
86    public org.omg.DynamicAny.DynAny copy() {
87        if (status == STATUS_DESTROYED) {
88            throw new OBJECT_NOT_EXIST();
89        }
90        DynAnyComplexImpl returnValue = null;
91        if ((representations & REPRESENTATION_ANY) != 0) {
92            // The flag "true" indicates copying the Any value
93            returnValue = (DynAnyComplexImpl)DynAnyUtil.createMostDerivedDynAny(any, orb, true);
94        }
95        if ((representations & REPRESENTATION_COMPONENTS) != 0) {
96        }
97        return returnValue;
98    }
99*/
100
101    //
102    // Complex methods
103    //
104
105    public String current_member_name ()
106        throws org.omg.DynamicAny.DynAnyPackage.TypeMismatch,
107               org.omg.DynamicAny.DynAnyPackage.InvalidValue
108    {
109        if (status == STATUS_DESTROYED) {
110            throw wrapper.dynAnyDestroyed() ;
111        }
112        if( ! checkInitComponents() || index < 0 || index >= names.length) {
113            throw new InvalidValue();
114        }
115        return names[index];
116    }
117
118    public TCKind current_member_kind ()
119        throws org.omg.DynamicAny.DynAnyPackage.TypeMismatch,
120               org.omg.DynamicAny.DynAnyPackage.InvalidValue
121    {
122        if (status == STATUS_DESTROYED) {
123            throw wrapper.dynAnyDestroyed() ;
124        }
125        if( ! checkInitComponents() || index < 0 || index >= components.length) {
126            throw new InvalidValue();
127        }
128        return components[index].type().kind();
129    }
130
131    // Creates references to the parameter instead of copying it.
132    public void set_members (org.omg.DynamicAny.NameValuePair[] value)
133        throws org.omg.DynamicAny.DynAnyPackage.TypeMismatch,
134               org.omg.DynamicAny.DynAnyPackage.InvalidValue
135    {
136        if (status == STATUS_DESTROYED) {
137            throw wrapper.dynAnyDestroyed() ;
138        }
139        if (value == null || value.length == 0) {
140            clearData();
141            return;
142        }
143
144        Any memberAny;
145        DynAny memberDynAny = null;
146        String memberName;
147        // We know that this is of kind tk_struct
148        TypeCode expectedTypeCode = any.type();
149
150        int expectedMemberCount = 0;
151        try {
152            expectedMemberCount = expectedTypeCode.member_count();
153        } catch (BadKind badKind) { // impossible
154        }
155        if (expectedMemberCount != value.length) {
156            clearData();
157            throw new InvalidValue();
158        }
159
160        allocComponents(value);
161
162        for (int i=0; i<value.length; i++) {
163            if (value[i] != null) {
164                memberName = value[i].id;
165                String expectedMemberName = null;
166                try {
167                    expectedMemberName = expectedTypeCode.member_name(i);
168                } catch (BadKind badKind) { // impossible
169                } catch (Bounds bounds) { // impossible
170                }
171                if ( ! (expectedMemberName.equals(memberName) || memberName.equals(""))) {
172                    clearData();
173                    // _REVISIT_ More info
174                    throw new TypeMismatch();
175                }
176                memberAny = value[i].value;
177                TypeCode expectedMemberType = null;
178                try {
179                    expectedMemberType = expectedTypeCode.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(memberAny, orb, false);
191                } catch (InconsistentTypeCode itc) {
192                    throw new InvalidValue();
193                }
194                addComponent(i, memberName, memberAny, memberDynAny);
195            } else {
196                clearData();
197                // _REVISIT_ More info
198                throw new InvalidValue();
199            }
200        }
201        index = (value.length == 0 ? NO_INDEX : 0);
202        representations = REPRESENTATION_COMPONENTS;
203    }
204
205    // Creates references to the parameter instead of copying it.
206    public void set_members_as_dyn_any (org.omg.DynamicAny.NameDynAnyPair[] value)
207        throws org.omg.DynamicAny.DynAnyPackage.TypeMismatch,
208               org.omg.DynamicAny.DynAnyPackage.InvalidValue
209    {
210        if (status == STATUS_DESTROYED) {
211            throw wrapper.dynAnyDestroyed() ;
212        }
213        if (value == null || value.length == 0) {
214            clearData();
215            return;
216        }
217
218        Any memberAny;
219        DynAny memberDynAny;
220        String memberName;
221        // We know that this is of kind tk_struct
222        TypeCode expectedTypeCode = any.type();
223
224        int expectedMemberCount = 0;
225        try {
226            expectedMemberCount = expectedTypeCode.member_count();
227        } catch (BadKind badKind) { // impossible
228        }
229        if (expectedMemberCount != value.length) {
230            clearData();
231            throw new InvalidValue();
232        }
233
234        allocComponents(value);
235
236        for (int i=0; i<value.length; i++) {
237            if (value[i] != null) {
238                memberName = value[i].id;
239                String expectedMemberName = null;
240                try {
241                    expectedMemberName = expectedTypeCode.member_name(i);
242                } catch (BadKind badKind) { // impossible
243                } catch (Bounds bounds) { // impossible
244                }
245                if ( ! (expectedMemberName.equals(memberName) || memberName.equals(""))) {
246                    clearData();
247                    // _REVISIT_ More info
248                    throw new TypeMismatch();
249                }
250                memberDynAny = value[i].value;
251                memberAny = getAny(memberDynAny);
252                TypeCode expectedMemberType = null;
253                try {
254                    expectedMemberType = expectedTypeCode.member_type(i);
255                } catch (BadKind badKind) { // impossible
256                } catch (Bounds bounds) { // impossible
257                }
258                if (! expectedMemberType.equal(memberAny.type())) {
259                    clearData();
260                    // _REVISIT_ More info
261                    throw new TypeMismatch();
262                }
263
264                addComponent(i, memberName, memberAny, memberDynAny);
265            } else {
266                clearData();
267                // _REVISIT_ More info
268                throw new InvalidValue();
269            }
270        }
271        index = (value.length == 0 ? NO_INDEX : 0);
272        representations = REPRESENTATION_COMPONENTS;
273    }
274
275    //
276    // Utility methods
277    //
278
279    private void allocComponents(int length) {
280        components = new DynAny[length];
281        names = new String[length];
282        nameValuePairs = new NameValuePair[length];
283        nameDynAnyPairs = new NameDynAnyPair[length];
284        for (int i=0; i<length; i++) {
285            nameValuePairs[i] = new NameValuePair();
286            nameDynAnyPairs[i] = new NameDynAnyPair();
287        }
288    }
289
290    private void allocComponents(org.omg.DynamicAny.NameValuePair[] value) {
291        components = new DynAny[value.length];
292        names = new String[value.length];
293        nameValuePairs = value;
294        nameDynAnyPairs = new NameDynAnyPair[value.length];
295        for (int i=0; i<value.length; i++) {
296            nameDynAnyPairs[i] = new NameDynAnyPair();
297        }
298    }
299
300    private void allocComponents(org.omg.DynamicAny.NameDynAnyPair[] value) {
301        components = new DynAny[value.length];
302        names = new String[value.length];
303        nameValuePairs = new NameValuePair[value.length];
304        for (int i=0; i<value.length; i++) {
305            nameValuePairs[i] = new NameValuePair();
306        }
307        nameDynAnyPairs = value;
308    }
309
310    private void addComponent(int i, String memberName, Any memberAny, DynAny memberDynAny) {
311        components[i] = memberDynAny;
312        names[i] = (memberName != null ? memberName : "");
313        nameValuePairs[i].id = memberName;
314        nameValuePairs[i].value = memberAny;
315        nameDynAnyPairs[i].id = memberName;
316        nameDynAnyPairs[i].value = memberDynAny;
317        if (memberDynAny instanceof DynAnyImpl)
318            ((DynAnyImpl)memberDynAny).setStatus(STATUS_UNDESTROYABLE);
319    }
320
321    // Initializes components, names, nameValuePairs and nameDynAnyPairs representation
322    // from the Any representation
323    protected boolean initializeComponentsFromAny() {
324        // This typeCode is of kind tk_struct.
325        TypeCode typeCode = any.type();
326        TypeCode memberType = null;
327        Any memberAny;
328        DynAny memberDynAny = null;
329        String memberName = null;
330        int length = 0;
331
332        try {
333            length = typeCode.member_count();
334        } catch (BadKind badKind) { // impossible
335        }
336
337        InputStream input = any.create_input_stream();
338
339        allocComponents(length);
340
341        for (int i=0; i<length; i++) {
342            try {
343                memberName = typeCode.member_name(i);
344                memberType = typeCode.member_type(i);
345            } catch (BadKind badKind) { // impossible
346            } catch (Bounds bounds) { // impossible
347            }
348            memberAny = DynAnyUtil.extractAnyFromStream(memberType, input, orb);
349            try {
350                // Creates the appropriate subtype without copying the Any
351                memberDynAny = DynAnyUtil.createMostDerivedDynAny(memberAny, orb, false);
352                // _DEBUG_
353                //System.out.println("Created DynAny for " + memberName +
354                //                   ", type " + memberType.kind().value());
355            } catch (InconsistentTypeCode itc) { // impossible
356            }
357            addComponent(i, memberName, memberAny, memberDynAny);
358        }
359        return true;
360    }
361
362    // Initializes components, names, nameValuePairs and nameDynAnyPairs representation
363    // from the internal TypeCode information with default values
364    // This is not done recursively, only one level.
365    // More levels are initialized lazily, on demand.
366    protected boolean initializeComponentsFromTypeCode() {
367        // This typeCode is of kind tk_struct.
368        TypeCode typeCode = any.type();
369        TypeCode memberType = null;
370        Any memberAny;
371        DynAny memberDynAny = null;
372        String memberName;
373        int length = 0;
374
375        try {
376            length = typeCode.member_count();
377        } catch (BadKind badKind) { // impossible
378        }
379
380        allocComponents(length);
381
382        for (int i=0; i<length; i++) {
383            memberName = null;
384            try {
385                memberName = typeCode.member_name(i);
386                memberType = typeCode.member_type(i);
387            } catch (BadKind badKind) { // impossible
388            } catch (Bounds bounds) { // impossible
389            }
390            try {
391                memberDynAny = DynAnyUtil.createMostDerivedDynAny(memberType, orb);
392                // _DEBUG_
393                //System.out.println("Created DynAny for " + memberName +
394                //                   ", type " + memberType.kind().value());
395/*
396                if (memberDynAny instanceof DynAnyConstructedImpl) {
397                    if ( ! ((DynAnyConstructedImpl)memberDynAny).isRecursive()) {
398                        // This is the recursive part
399                        ((DynAnyConstructedImpl)memberDynAny).initializeComponentsFromTypeCode();
400                    }
401                } // Other implementations have their own way of dealing with implementing the spec.
402*/
403            } catch (InconsistentTypeCode itc) { // impossible
404            }
405            // get a hold of the default initialized Any without copying
406            memberAny = getAny(memberDynAny);
407            addComponent(i, memberName, memberAny, memberDynAny);
408        }
409        return true;
410    }
411
412    // It is probably right not to destroy the released component DynAnys.
413    // Some other DynAny or a user variable might still hold onto them
414    // and if not then the garbage collector will take care of it.
415    protected void clearData() {
416        super.clearData();
417        names = null;
418        nameValuePairs = null;
419        nameDynAnyPairs = null;
420    }
421}
422