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 26 package com.sun.corba.se.impl.dynamicany; 27 28 import org.omg.CORBA.TypeCode; 29 import org.omg.CORBA.TCKind; 30 import org.omg.CORBA.Any; 31 import org.omg.CORBA.TypeCodePackage.BadKind; 32 import org.omg.CORBA.TypeCodePackage.Bounds; 33 import org.omg.CORBA.portable.InputStream; 34 import org.omg.DynamicAny.*; 35 import org.omg.DynamicAny.DynAnyPackage.TypeMismatch; 36 import org.omg.DynamicAny.DynAnyPackage.InvalidValue; 37 import org.omg.DynamicAny.DynAnyFactoryPackage.InconsistentTypeCode; 38 39 import com.sun.corba.se.spi.orb.ORB ; 40 import com.sun.corba.se.spi.logging.CORBALogDomains ; 41 import com.sun.corba.se.impl.logging.ORBUtilSystemException ; 42 43 abstract 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 }