1. /*
  2. * @(#)AnyImpl.java 1.65 04/05/18
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. /*
  8. * Licensed Materials - Property of IBM
  9. * RMI-IIOP v1.0
  10. * Copyright IBM Corp. 1998 1999 All Rights Reserved
  11. *
  12. * US Government Users Restricted Rights - Use, duplication or
  13. * disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  14. */
  15. package com.sun.corba.se.impl.corba;
  16. import java.io.Serializable;
  17. import java.math.BigDecimal;
  18. import java.util.List ;
  19. import java.util.ArrayList ;
  20. import org.omg.CORBA.Principal ;
  21. import org.omg.CORBA.TypeCode ;
  22. import org.omg.CORBA.Any ;
  23. import org.omg.CORBA.CompletionStatus ;
  24. import org.omg.CORBA.TCKind ;
  25. import org.omg.CORBA.portable.Streamable;
  26. import org.omg.CORBA.portable.InputStream;
  27. import org.omg.CORBA.portable.OutputStream;
  28. import org.omg.CORBA.TypeCodePackage.BadKind;
  29. import org.omg.CORBA.TypeCodePackage.Bounds;
  30. import com.sun.corba.se.spi.orb.ORB;
  31. import com.sun.corba.se.spi.orb.ORBVersionFactory;
  32. import com.sun.corba.se.spi.logging.CORBALogDomains;
  33. import com.sun.corba.se.spi.presentation.rmi.StubAdapter;
  34. import com.sun.corba.se.impl.encoding.CDRInputStream;
  35. import com.sun.corba.se.impl.encoding.EncapsInputStream;
  36. import com.sun.corba.se.impl.encoding.EncapsOutputStream;
  37. import com.sun.corba.se.impl.io.ValueUtility;
  38. import com.sun.corba.se.impl.orbutil.RepositoryIdFactory;
  39. import com.sun.corba.se.impl.orbutil.RepositoryIdStrings;
  40. import com.sun.corba.se.impl.orbutil.ORBUtility;
  41. import com.sun.corba.se.impl.logging.ORBUtilSystemException;
  42. // subclasses must provide a matching helper class
  43. public class AnyImpl extends Any
  44. {
  45. private static final class AnyInputStream extends EncapsInputStream
  46. {
  47. public AnyInputStream(EncapsInputStream theStream )
  48. {
  49. super( theStream );
  50. }
  51. }
  52. private static final class AnyOutputStream extends EncapsOutputStream
  53. {
  54. public AnyOutputStream(ORB orb)
  55. {
  56. super((ORB)orb);
  57. }
  58. public org.omg.CORBA.portable.InputStream create_input_stream()
  59. {
  60. return new AnyInputStream(
  61. (com.sun.corba.se.impl.encoding.EncapsInputStream)
  62. super.create_input_stream());
  63. }
  64. }
  65. //
  66. // Always valid.
  67. //
  68. private TypeCodeImpl typeCode;
  69. protected ORB orb;
  70. private ORBUtilSystemException wrapper ;
  71. //
  72. // Validity depends upon typecode. The 'value' and 'object' instance
  73. // members are used to hold immutable types as defined by the
  74. // isStreamed[] table below. Otherwise, 'stream' is non-null and
  75. // holds the value in CDR marshaled format. As an optimization, the
  76. // stream type is an Any extension of CDR stream that is used to
  77. // detect an optimization in read_value().
  78. //
  79. private CDRInputStream stream;
  80. private long value;
  81. private java.lang.Object object;
  82. // Setting the typecode via the type() accessor wipes out the value.
  83. // An attempt to extract before the value is set will result
  84. // in a BAD_OPERATION exception being raised.
  85. private boolean isInitialized = false;
  86. private static final int DEFAULT_BUFFER_SIZE = 32;
  87. /*
  88. * This boolean array tells us if a given typecode must be
  89. * streamed. Objects that are immutable don't have to be streamed.
  90. */
  91. static boolean isStreamed[] = {
  92. false, // null
  93. false, // void
  94. false, // short
  95. false, // long
  96. false, // ushort
  97. false, // ulong
  98. false, // float
  99. false, // double
  100. false, // boolean
  101. false, // char
  102. false, // octet
  103. false, // any
  104. false, // TypeCode
  105. true, // Principal
  106. false, // objref
  107. true, // struct
  108. true, // union
  109. false, // enum
  110. false, // string
  111. true, // sequence
  112. true, // array
  113. true, // alias
  114. true, // except
  115. false, // longlong
  116. false, // ulonglong
  117. false, // longdouble
  118. false, // wchar
  119. false, // wstring
  120. false, // fixed
  121. false, // value
  122. false, // value_box (used to be true)
  123. false, // native
  124. false // abstract interface
  125. };
  126. static AnyImpl convertToNative(ORB orb, Any any) {
  127. if (any instanceof AnyImpl) {
  128. return (AnyImpl)any;
  129. } else {
  130. AnyImpl anyImpl = new AnyImpl(orb, any);
  131. anyImpl.typeCode = TypeCodeImpl.convertToNative(orb, anyImpl.typeCode);
  132. return anyImpl;
  133. }
  134. }
  135. ///////////////////////////////////////////////////////////////////////////
  136. // Constructors
  137. /**
  138. * A constructor that sets the Any to contain a null. It also marks
  139. * the value as being invalid so that extractions throw an exception
  140. * until an insertion has been performed.
  141. */
  142. public AnyImpl(ORB orb)
  143. {
  144. this.orb = orb;
  145. wrapper = ORBUtilSystemException.get( (com.sun.corba.se.spi.orb.ORB)orb,
  146. CORBALogDomains.RPC_PRESENTATION ) ;
  147. typeCode = orb.get_primitive_tc(TCKind._tk_null);
  148. stream = null;
  149. object = null;
  150. value = 0;
  151. // null is a valid value
  152. isInitialized = true;
  153. }
  154. //
  155. // Create a new AnyImpl which is a copy of obj.
  156. //
  157. public AnyImpl(ORB orb, Any obj) {
  158. this(orb);
  159. if ((obj instanceof AnyImpl)) {
  160. AnyImpl objImpl = (AnyImpl)obj;
  161. typeCode = objImpl.typeCode;
  162. value = objImpl.value;
  163. object = objImpl.object;
  164. isInitialized = objImpl.isInitialized;
  165. if (objImpl.stream != null)
  166. stream = objImpl.stream.dup();
  167. } else {
  168. read_value(obj.create_input_stream(), obj.type());
  169. }
  170. }
  171. ///////////////////////////////////////////////////////////////////////////
  172. // basic accessors
  173. /**
  174. * returns the type of the element contained in the Any.
  175. *
  176. * @result the TypeCode for the element in the Any
  177. */
  178. public TypeCode type() {
  179. return typeCode;
  180. }
  181. private TypeCode realType() {
  182. return realType(typeCode);
  183. }
  184. private TypeCode realType(TypeCode aType) {
  185. TypeCode realType = aType;
  186. try {
  187. // Note: Indirect types are handled in kind() method
  188. while (realType.kind().value() == TCKind._tk_alias) {
  189. realType = realType.content_type();
  190. }
  191. } catch (BadKind bad) { // impossible
  192. throw wrapper.badkindCannotOccur( bad ) ;
  193. }
  194. return realType;
  195. }
  196. /**
  197. * sets the type of the element to be contained in the Any.
  198. *
  199. * @param tc the TypeCode for the element in the Any
  200. */
  201. public void type(TypeCode tc)
  202. {
  203. //debug.log ("type2");
  204. // set the typecode
  205. typeCode = TypeCodeImpl.convertToNative(orb, tc);
  206. stream = null;
  207. value = 0;
  208. object = null;
  209. // null is the only legal value this Any can have after resetting the type code
  210. isInitialized = (tc.kind().value() == TCKind._tk_null);
  211. }
  212. /**
  213. * checks for equality between Anys.
  214. *
  215. * @param otherAny the Any to be compared with.
  216. * @result true if the Anys are equal, false otherwise.
  217. */
  218. public boolean equal(Any otherAny)
  219. {
  220. //debug.log ("equal");
  221. if (otherAny == this)
  222. return true;
  223. // first check for typecode equality.
  224. // note that this will take aliases into account
  225. if (!typeCode.equal(otherAny.type()))
  226. return false;
  227. // Resolve aliases here
  228. TypeCode realType = realType();
  229. // _REVISIT_ Possible optimization for the case where
  230. // otherAny is a AnyImpl and the endianesses match.
  231. // Need implementation of CDRInputStream.equals()
  232. // For now we disable this to encourage testing the generic,
  233. // unoptimized code below.
  234. // Unfortunately this generic code needs to copy the whole stream
  235. // at least once.
  236. // if (AnyImpl.isStreamed[realType.kind().value()]) {
  237. // if (otherAny instanceof AnyImpl) {
  238. // return ((AnyImpl)otherAny).stream.equals(stream);
  239. // }
  240. // }
  241. switch (realType.kind().value()) {
  242. // handle primitive types
  243. case TCKind._tk_null:
  244. case TCKind._tk_void:
  245. return true;
  246. case TCKind._tk_short:
  247. return (extract_short() == otherAny.extract_short());
  248. case TCKind._tk_long:
  249. return (extract_long() == otherAny.extract_long());
  250. case TCKind._tk_ushort:
  251. return (extract_ushort() == otherAny.extract_ushort());
  252. case TCKind._tk_ulong:
  253. return (extract_ulong() == otherAny.extract_ulong());
  254. case TCKind._tk_float:
  255. return (extract_float() == otherAny.extract_float());
  256. case TCKind._tk_double:
  257. return (extract_double() == otherAny.extract_double());
  258. case TCKind._tk_boolean:
  259. return (extract_boolean() == otherAny.extract_boolean());
  260. case TCKind._tk_char:
  261. return (extract_char() == otherAny.extract_char());
  262. case TCKind._tk_wchar:
  263. return (extract_wchar() == otherAny.extract_wchar());
  264. case TCKind._tk_octet:
  265. return (extract_octet() == otherAny.extract_octet());
  266. case TCKind._tk_any:
  267. return extract_any().equal(otherAny.extract_any());
  268. case TCKind._tk_TypeCode:
  269. return extract_TypeCode().equal(otherAny.extract_TypeCode());
  270. case TCKind._tk_string:
  271. return extract_string().equals(otherAny.extract_string());
  272. case TCKind._tk_wstring:
  273. return (extract_wstring().equals(otherAny.extract_wstring()));
  274. case TCKind._tk_longlong:
  275. return (extract_longlong() == otherAny.extract_longlong());
  276. case TCKind._tk_ulonglong:
  277. return (extract_ulonglong() == otherAny.extract_ulonglong());
  278. case TCKind._tk_objref:
  279. return (extract_Object().equals(otherAny.extract_Object()));
  280. case TCKind._tk_Principal:
  281. return (extract_Principal().equals(otherAny.extract_Principal()));
  282. case TCKind._tk_enum:
  283. return (extract_long() == otherAny.extract_long());
  284. case TCKind._tk_fixed:
  285. return (extract_fixed().compareTo(otherAny.extract_fixed()) == 0);
  286. case TCKind._tk_except:
  287. case TCKind._tk_struct:
  288. case TCKind._tk_union:
  289. case TCKind._tk_sequence:
  290. case TCKind._tk_array:
  291. InputStream copyOfMyStream = this.create_input_stream();
  292. InputStream copyOfOtherStream = otherAny.create_input_stream();
  293. return equalMember(realType, copyOfMyStream, copyOfOtherStream);
  294. // Too complicated to handle value types the way we handle
  295. // other complex types above. Don't try to decompose it here
  296. // for faster comparison, just use Object.equals().
  297. case TCKind._tk_value:
  298. case TCKind._tk_value_box:
  299. return extract_Value().equals(otherAny.extract_Value());
  300. case TCKind._tk_alias:
  301. throw wrapper.errorResolvingAlias() ;
  302. case TCKind._tk_longdouble:
  303. // Unspecified for Java
  304. throw wrapper.tkLongDoubleNotSupported() ;
  305. default:
  306. throw wrapper.typecodeNotSupported() ;
  307. }
  308. }
  309. // Needed for equal() in order to achieve linear performance for complex types.
  310. // Uses up (recursively) copies of the InputStream in both Anys that got created in equal().
  311. private boolean equalMember(TypeCode memberType, InputStream myStream, InputStream otherStream) {
  312. // Resolve aliases here
  313. TypeCode realType = realType(memberType);
  314. try {
  315. switch (realType.kind().value()) {
  316. // handle primitive types
  317. case TCKind._tk_null:
  318. case TCKind._tk_void:
  319. return true;
  320. case TCKind._tk_short:
  321. return (myStream.read_short() == otherStream.read_short());
  322. case TCKind._tk_long:
  323. return (myStream.read_long() == otherStream.read_long());
  324. case TCKind._tk_ushort:
  325. return (myStream.read_ushort() == otherStream.read_ushort());
  326. case TCKind._tk_ulong:
  327. return (myStream.read_ulong() == otherStream.read_ulong());
  328. case TCKind._tk_float:
  329. return (myStream.read_float() == otherStream.read_float());
  330. case TCKind._tk_double:
  331. return (myStream.read_double() == otherStream.read_double());
  332. case TCKind._tk_boolean:
  333. return (myStream.read_boolean() == otherStream.read_boolean());
  334. case TCKind._tk_char:
  335. return (myStream.read_char() == otherStream.read_char());
  336. case TCKind._tk_wchar:
  337. return (myStream.read_wchar() == otherStream.read_wchar());
  338. case TCKind._tk_octet:
  339. return (myStream.read_octet() == otherStream.read_octet());
  340. case TCKind._tk_any:
  341. return myStream.read_any().equal(otherStream.read_any());
  342. case TCKind._tk_TypeCode:
  343. return myStream.read_TypeCode().equal(otherStream.read_TypeCode());
  344. case TCKind._tk_string:
  345. return myStream.read_string().equals(otherStream.read_string());
  346. case TCKind._tk_wstring:
  347. return (myStream.read_wstring().equals(otherStream.read_wstring()));
  348. case TCKind._tk_longlong:
  349. return (myStream.read_longlong() == otherStream.read_longlong());
  350. case TCKind._tk_ulonglong:
  351. return (myStream.read_ulonglong() == otherStream.read_ulonglong());
  352. case TCKind._tk_objref:
  353. return (myStream.read_Object().equals(otherStream.read_Object()));
  354. case TCKind._tk_Principal:
  355. return (myStream.read_Principal().equals(otherStream.read_Principal()));
  356. case TCKind._tk_enum:
  357. return (myStream.read_long() == otherStream.read_long());
  358. case TCKind._tk_fixed:
  359. return (myStream.read_fixed().compareTo(otherStream.read_fixed()) == 0);
  360. case TCKind._tk_except:
  361. case TCKind._tk_struct: {
  362. int length = realType.member_count();
  363. for (int i=0; i<length; i++) {
  364. if ( ! equalMember(realType.member_type(i), myStream, otherStream)) {
  365. return false;
  366. }
  367. }
  368. return true;
  369. }
  370. case TCKind._tk_union: {
  371. Any myDiscriminator = orb.create_any();
  372. Any otherDiscriminator = orb.create_any();
  373. myDiscriminator.read_value(myStream, realType.discriminator_type());
  374. otherDiscriminator.read_value(otherStream, realType.discriminator_type());
  375. if ( ! myDiscriminator.equal(otherDiscriminator)) {
  376. return false;
  377. }
  378. TypeCodeImpl realTypeCodeImpl = TypeCodeImpl.convertToNative(orb, realType);
  379. int memberIndex = realTypeCodeImpl.currentUnionMemberIndex(myDiscriminator);
  380. if (memberIndex == -1)
  381. throw wrapper.unionDiscriminatorError() ;
  382. if ( ! equalMember(realType.member_type(memberIndex), myStream, otherStream)) {
  383. return false;
  384. }
  385. return true;
  386. }
  387. case TCKind._tk_sequence: {
  388. int length = myStream.read_long();
  389. otherStream.read_long(); // just so that the two stream are in sync
  390. for (int i=0; i<length; i++) {
  391. if ( ! equalMember(realType.content_type(), myStream, otherStream)) {
  392. return false;
  393. }
  394. }
  395. return true;
  396. }
  397. case TCKind._tk_array: {
  398. int length = realType.member_count();
  399. for (int i=0; i<length; i++) {
  400. if ( ! equalMember(realType.content_type(), myStream, otherStream)) {
  401. return false;
  402. }
  403. }
  404. return true;
  405. }
  406. // Too complicated to handle value types the way we handle
  407. // other complex types above. Don't try to decompose it here
  408. // for faster comparison, just use Object.equals().
  409. case TCKind._tk_value:
  410. case TCKind._tk_value_box:
  411. org.omg.CORBA_2_3.portable.InputStream mine =
  412. (org.omg.CORBA_2_3.portable.InputStream)myStream;
  413. org.omg.CORBA_2_3.portable.InputStream other =
  414. (org.omg.CORBA_2_3.portable.InputStream)otherStream;
  415. return mine.read_value().equals(other.read_value());
  416. case TCKind._tk_alias:
  417. // error resolving alias above
  418. throw wrapper.errorResolvingAlias() ;
  419. case TCKind._tk_longdouble:
  420. throw wrapper.tkLongDoubleNotSupported() ;
  421. default:
  422. throw wrapper.typecodeNotSupported() ;
  423. }
  424. } catch (BadKind badKind) { // impossible
  425. throw wrapper.badkindCannotOccur() ;
  426. } catch (Bounds bounds) { // impossible
  427. throw wrapper.boundsCannotOccur() ;
  428. }
  429. }
  430. ///////////////////////////////////////////////////////////////////////////
  431. // accessors for marshaling/unmarshaling
  432. /**
  433. * returns an output stream that an Any value can be marshaled into.
  434. *
  435. * @result the OutputStream to marshal value of Any into
  436. */
  437. public org.omg.CORBA.portable.OutputStream create_output_stream()
  438. {
  439. //debug.log ("create_output_stream");
  440. return new AnyOutputStream(orb);
  441. }
  442. /**
  443. * returns an input stream that an Any value can be marshaled out of.
  444. *
  445. * @result the InputStream to marshal value of Any out of.
  446. */
  447. public org.omg.CORBA.portable.InputStream create_input_stream()
  448. {
  449. //
  450. // We create a new InputStream so that multiple threads can call here
  451. // and read the streams in parallel without thread safety problems.
  452. //
  453. //debug.log ("create_input_stream");
  454. if (AnyImpl.isStreamed[realType().kind().value()]) {
  455. return stream.dup();
  456. } else {
  457. OutputStream os = (OutputStream)orb.create_output_stream();
  458. TCUtility.marshalIn(os, realType(), value, object);
  459. return os.create_input_stream();
  460. }
  461. }
  462. ///////////////////////////////////////////////////////////////////////////
  463. // marshaling/unmarshaling routines
  464. //
  465. // If the InputStream is a CDRInputStream then we can copy the bytes
  466. // since it is in our format and does not have alignment issues.
  467. //
  468. public void read_value(org.omg.CORBA.portable.InputStream in, TypeCode tc)
  469. {
  470. //debug.log ("read_value");
  471. //
  472. // Assume that someone isn't going to think they can keep reading
  473. // from this stream after calling us. That would be likely for
  474. // an IIOPInputStream but if it is an AnyInputStream then they
  475. // presumably obtained it via our create_output_stream() so they could
  476. // write the contents of an IDL data type to it and then call
  477. // create_input_stream() for us to read it. This is how Helper classes
  478. // typically implement the insert() method.
  479. // We should probably document this behavior in the 1.1 revision
  480. // task force.
  481. //
  482. typeCode = TypeCodeImpl.convertToNative(orb, tc);
  483. int kind = realType().kind().value();
  484. if (kind >= isStreamed.length) {
  485. throw wrapper.invalidIsstreamedTckind( CompletionStatus.COMPLETED_MAYBE,
  486. new Integer(kind)) ;
  487. }
  488. if (AnyImpl.isStreamed[kind]) {
  489. if ( in instanceof AnyInputStream ) {
  490. // could only have been created here
  491. stream = (CDRInputStream)in;
  492. } else {
  493. org.omg.CORBA_2_3.portable.OutputStream out =
  494. (org.omg.CORBA_2_3.portable.OutputStream)orb.create_output_stream();
  495. typeCode.copy((org.omg.CORBA_2_3.portable.InputStream)in, out);
  496. stream = (CDRInputStream)out.create_input_stream();
  497. }
  498. } else {
  499. java.lang.Object[] objholder = new java.lang.Object[1];
  500. objholder[0] = object;
  501. long[] longholder = new long[1];
  502. TCUtility.unmarshalIn(in, typeCode, longholder, objholder);
  503. value = longholder[0];
  504. object = objholder[0];
  505. stream = null;
  506. }
  507. isInitialized = true;
  508. }
  509. //
  510. // We could optimize this by noticing whether the target stream
  511. // has ever had anything marshaled on it that required an
  512. // alignment of greater than 4 (was write_double() ever called on it).
  513. // If not, then we can just do a byte array copy without having to
  514. // drive the remarshaling through typecode interpretation.
  515. //
  516. public void write_value(OutputStream out)
  517. {
  518. //debug.log ("write_value");
  519. if (AnyImpl.isStreamed[realType().kind().value()]) {
  520. typeCode.copy(stream.dup(), out);
  521. } else {
  522. // _REVISIT_ check isInitialized whether all we write is TypeCode!
  523. TCUtility.marshalIn(out, realType(), value, object);
  524. }
  525. }
  526. /**
  527. * takes a streamable and inserts its reference into the any
  528. *
  529. * @param s the streamable to insert
  530. */
  531. public void insert_Streamable(Streamable s)
  532. {
  533. //debug.log ("insert_Streamable");
  534. typeCode = TypeCodeImpl.convertToNative(orb, s._type());
  535. object = s;
  536. isInitialized = true;
  537. }
  538. public Streamable extract_Streamable()
  539. {
  540. //debug.log( "extract_Streamable" ) ;
  541. return (Streamable)object;
  542. }
  543. ///////////////////////////////////////////////////////////////////////////
  544. // insertion/extraction/replacement for all basic types
  545. /**
  546. * See the description of the <a href="#anyOps">general Any operations.</a>
  547. */
  548. public void insert_short(short s)
  549. {
  550. //debug.log ("insert_short");
  551. typeCode = orb.get_primitive_tc(TCKind._tk_short);
  552. value = s;
  553. isInitialized = true;
  554. }
  555. private String getTCKindName( int tc )
  556. {
  557. if ((tc >= 0) && (tc < TypeCodeImpl.kindNames.length))
  558. return TypeCodeImpl.kindNames[tc] ;
  559. else
  560. return "UNKNOWN(" + tc + ")" ;
  561. }
  562. private void checkExtractBadOperation( int expected )
  563. {
  564. if (!isInitialized)
  565. throw wrapper.extractNotInitialized() ;
  566. int tc = realType().kind().value() ;
  567. if (tc != expected) {
  568. String tcName = getTCKindName( tc ) ;
  569. String expectedName = getTCKindName( expected ) ;
  570. throw wrapper.extractWrongType( expectedName, tcName ) ;
  571. }
  572. }
  573. private void checkExtractBadOperationList( int[] expected )
  574. {
  575. if (!isInitialized)
  576. throw wrapper.extractNotInitialized() ;
  577. int tc = realType().kind().value() ;
  578. for (int ctr=0; ctr<expected.length; ctr++)
  579. if (tc == expected[ctr])
  580. return ;
  581. List list = new ArrayList() ;
  582. for (int ctr=0; ctr<expected.length; ctr++)
  583. list.add( getTCKindName( expected[ctr] ) ) ;
  584. String tcName = getTCKindName( tc ) ;
  585. throw wrapper.extractWrongTypeList( list, tcName ) ;
  586. }
  587. /**
  588. * See the description of the <a href="#anyOps">general Any operations.</a>
  589. */
  590. public short extract_short()
  591. {
  592. //debug.log ("extract_short");
  593. checkExtractBadOperation( TCKind._tk_short ) ;
  594. return (short)value;
  595. }
  596. /**
  597. * See the description of the <a href="#anyOps">general Any operations.</a>
  598. */
  599. public void insert_long(int l)
  600. {
  601. //debug.log ("insert_long");
  602. // A long value is applicable to enums as well, so don't erase the enum type code
  603. // in case it was initialized that way before.
  604. int kind = realType().kind().value();
  605. if (kind != TCKind._tk_long && kind != TCKind._tk_enum) {
  606. typeCode = orb.get_primitive_tc(TCKind._tk_long);
  607. }
  608. value = l;
  609. isInitialized = true;
  610. }
  611. /**
  612. * See the description of the <a href="#anyOps">general Any operations.</a>
  613. */
  614. public int extract_long()
  615. {
  616. //debug.log ("extract_long");
  617. checkExtractBadOperationList( new int[] { TCKind._tk_long, TCKind._tk_enum } ) ;
  618. return (int)value;
  619. }
  620. /**
  621. * See the description of the <a href="#anyOps">general Any operations.</a>
  622. */
  623. public void insert_ushort(short s)
  624. {
  625. //debug.log ("insert_ushort");
  626. typeCode = orb.get_primitive_tc(TCKind._tk_ushort);
  627. value = s;
  628. isInitialized = true;
  629. }
  630. /**
  631. * See the description of the <a href="#anyOps">general Any operations.</a>
  632. */
  633. public short extract_ushort()
  634. {
  635. //debug.log ("extract_ushort");
  636. checkExtractBadOperation( TCKind._tk_ushort ) ;
  637. return (short)value;
  638. }
  639. /**
  640. * See the description of the <a href="#anyOps">general Any operations.</a>
  641. */
  642. public void insert_ulong(int l)
  643. {
  644. //debug.log ("insert_ulong");
  645. typeCode = orb.get_primitive_tc(TCKind._tk_ulong);
  646. value = l;
  647. isInitialized = true;
  648. }
  649. /**
  650. * See the description of the <a href="#anyOps">general Any operations.</a>
  651. */
  652. public int extract_ulong()
  653. {
  654. //debug.log ("extract_ulong");
  655. checkExtractBadOperation( TCKind._tk_ulong ) ;
  656. return (int)value;
  657. }
  658. /**
  659. * See the description of the <a href="#anyOps">general Any operations.</a>
  660. */
  661. public void insert_float(float f)
  662. {
  663. //debug.log ("insert_float");
  664. typeCode = orb.get_primitive_tc(TCKind._tk_float);
  665. value = Float.floatToIntBits(f);
  666. isInitialized = true;
  667. }
  668. /**
  669. * See the description of the <a href="#anyOps">general Any operations.</a>
  670. */
  671. public float extract_float()
  672. {
  673. //debug.log ("extract_float");
  674. checkExtractBadOperation( TCKind._tk_float ) ;
  675. return Float.intBitsToFloat((int)value);
  676. }
  677. /**
  678. * See the description of the <a href="#anyOps">general Any operations.</a>
  679. */
  680. public void insert_double(double d)
  681. {
  682. //debug.log ("insert_double");
  683. typeCode = orb.get_primitive_tc(TCKind._tk_double);
  684. value = Double.doubleToLongBits(d);
  685. isInitialized = true;
  686. }
  687. /**
  688. * See the description of the <a href="#anyOps">general Any operations.</a>
  689. */
  690. public double extract_double()
  691. {
  692. //debug.log ("extract_double");
  693. checkExtractBadOperation( TCKind._tk_double ) ;
  694. return Double.longBitsToDouble(value);
  695. }
  696. /**
  697. * See the description of the <a href="#anyOps">general Any operations.</a>
  698. */
  699. public void insert_longlong(long l)
  700. {
  701. //debug.log ("insert_longlong");
  702. typeCode = orb.get_primitive_tc(TCKind._tk_longlong);
  703. value = l;
  704. isInitialized = true;
  705. }
  706. /**
  707. * See the description of the <a href="#anyOps">general Any operations.</a>
  708. */
  709. public long extract_longlong()
  710. {
  711. //debug.log ("extract_longlong");
  712. checkExtractBadOperation( TCKind._tk_longlong ) ;
  713. return value;
  714. }
  715. /**
  716. * See the description of the <a href="#anyOps">general Any operations.</a>
  717. */
  718. public void insert_ulonglong(long l)
  719. {
  720. //debug.log ("insert_ulonglong");
  721. typeCode = orb.get_primitive_tc(TCKind._tk_ulonglong);
  722. value = l;
  723. isInitialized = true;
  724. }
  725. /**
  726. * See the description of the <a href="#anyOps">general Any operations.</a>
  727. */
  728. public long extract_ulonglong()
  729. {
  730. //debug.log ("extract_ulonglong");
  731. checkExtractBadOperation( TCKind._tk_ulonglong ) ;
  732. return value;
  733. }
  734. /**
  735. * See the description of the <a href="#anyOps">general Any operations.</a>
  736. */
  737. public void insert_boolean(boolean b)
  738. {
  739. //debug.log ("insert_boolean");
  740. typeCode = orb.get_primitive_tc(TCKind._tk_boolean);
  741. value = (b)? 1:0;
  742. isInitialized = true;
  743. }
  744. /**
  745. * See the description of the <a href="#anyOps">general Any operations.</a>
  746. */
  747. public boolean extract_boolean()
  748. {
  749. //debug.log ("extract_boolean");
  750. checkExtractBadOperation( TCKind._tk_boolean ) ;
  751. return (value == 0)? false: true;
  752. }
  753. /**
  754. * See the description of the <a href="#anyOps">general Any operations.</a>
  755. */
  756. public void insert_char(char c)
  757. {
  758. //debug.log ("insert_char");
  759. typeCode = orb.get_primitive_tc(TCKind._tk_char);
  760. value = c;
  761. isInitialized = true;
  762. }
  763. /**
  764. * See the description of the <a href="#anyOps">general Any operations.</a>
  765. */
  766. public char extract_char()
  767. {
  768. //debug.log ("extract_char");
  769. checkExtractBadOperation( TCKind._tk_char ) ;
  770. return (char)value;
  771. }
  772. /**
  773. * See the description of the <a href="#anyOps">general Any operations.</a>
  774. */
  775. public void insert_wchar(char c)
  776. {
  777. //debug.log ("insert_wchar");
  778. typeCode = orb.get_primitive_tc(TCKind._tk_wchar);
  779. value = c;
  780. isInitialized = true;
  781. }
  782. /**
  783. * See the description of the <a href="#anyOps">general Any operations.</a>
  784. */
  785. public char extract_wchar()
  786. {
  787. //debug.log ("extract_wchar");
  788. checkExtractBadOperation( TCKind._tk_wchar ) ;
  789. return (char)value;
  790. }
  791. /**
  792. * See the description of the <a href="#anyOps">general Any operations.</a>
  793. */
  794. public void insert_octet(byte b)
  795. {
  796. //debug.log ("insert_octet");
  797. typeCode = orb.get_primitive_tc(TCKind._tk_octet);
  798. value = b;
  799. isInitialized = true;
  800. }
  801. /**
  802. * See the description of the <a href="#anyOps">general Any operations.</a>
  803. */
  804. public byte extract_octet()
  805. {
  806. //debug.log ("extract_octet");
  807. checkExtractBadOperation( TCKind._tk_octet ) ;
  808. return (byte)value;
  809. }
  810. /**
  811. * See the description of the <a href="#anyOps">general Any operations.</a>
  812. */
  813. public void insert_string(String s)
  814. {
  815. //debug.log ("insert_string");
  816. // Make sure type code information for bounded strings is not erased
  817. if (typeCode.kind() == TCKind.tk_string) {
  818. int length = 0;
  819. try {
  820. length = typeCode.length();
  821. } catch (BadKind bad) {
  822. throw wrapper.badkindCannotOccur() ;
  823. }
  824. // Check if bounded strings length is not exceeded
  825. if (length != 0 && s != null && s.length() > length) {
  826. throw wrapper.badStringBounds( new Integer(s.length()),
  827. new Integer(length) ) ;
  828. }
  829. } else {
  830. typeCode = orb.get_primitive_tc(TCKind._tk_string);
  831. }
  832. object = s;
  833. isInitialized = true;
  834. }
  835. /**
  836. * See the description of the <a href="#anyOps">general Any operations.</a>
  837. */
  838. public String extract_string()
  839. {
  840. //debug.log ("extract_string");
  841. checkExtractBadOperation( TCKind._tk_string ) ;
  842. return (String)object;
  843. }
  844. /**
  845. * See the description of the <a href="#anyOps">general Any operations.</a>
  846. */
  847. public void insert_wstring(String s)
  848. {
  849. //debug.log ("insert_wstring");
  850. // Make sure type code information for bounded strings is not erased
  851. if (typeCode.kind() == TCKind.tk_wstring) {
  852. int length = 0;
  853. try {
  854. length = typeCode.length();
  855. } catch (BadKind bad) {
  856. throw wrapper.badkindCannotOccur() ;
  857. }
  858. // Check if bounded strings length is not exceeded
  859. if (length != 0 && s != null && s.length() > length) {
  860. throw wrapper.badStringBounds( new Integer(s.length()),
  861. new Integer(length) ) ;
  862. }
  863. } else {
  864. typeCode = orb.get_primitive_tc(TCKind._tk_wstring);
  865. }
  866. object = s;
  867. isInitialized = true;
  868. }
  869. /**
  870. * See the description of the <a href="#anyOps">general Any operations.</a>
  871. */
  872. public String extract_wstring()
  873. {
  874. //debug.log ("extract_wstring");
  875. checkExtractBadOperation( TCKind._tk_wstring ) ;
  876. return (String)object;
  877. }
  878. /**
  879. * See the description of the <a href="#anyOps">general Any operations.</a>
  880. */
  881. public void insert_any(Any a)
  882. {
  883. //debug.log ("insert_any");
  884. typeCode = orb.get_primitive_tc(TCKind._tk_any);
  885. object = a;
  886. stream = null;
  887. isInitialized = true;
  888. }
  889. /**
  890. * See the description of the <a href="#anyOps">general Any operations.</a>
  891. */
  892. public Any extract_any()
  893. {
  894. //debug.log ("extract_any");
  895. checkExtractBadOperation( TCKind._tk_any ) ;
  896. return (Any)object;
  897. }
  898. /**
  899. * See the description of the <a href="#anyOps">general Any operations.</a>
  900. */
  901. public void insert_Object(org.omg.CORBA.Object o)
  902. {
  903. //debug.log ("insert_Object");
  904. if ( o == null ) {
  905. typeCode = orb.get_primitive_tc(TCKind._tk_objref);
  906. } else {
  907. if (StubAdapter.isStub(o)) {
  908. String[] ids = StubAdapter.getTypeIds( o ) ;
  909. typeCode = new TypeCodeImpl(orb, TCKind._tk_objref, ids[0], "");
  910. } else {
  911. throw wrapper.badInsertobjParam(
  912. CompletionStatus.COMPLETED_MAYBE, o.getClass().getName() ) ;
  913. }
  914. }
  915. object = o;
  916. isInitialized = true;
  917. }
  918. /**
  919. * A variant of the insertion operation that takes a typecode
  920. * argument as well.
  921. */
  922. public void insert_Object(org.omg.CORBA.Object o, TypeCode tc)
  923. {
  924. //debug.log ("insert_Object2");
  925. try {
  926. if ( tc.id().equals("IDL:omg.org/CORBA/Object:1.0") || o._is_a(tc.id()) )
  927. {
  928. typeCode = TypeCodeImpl.convertToNative(orb, tc);
  929. object = o;
  930. }
  931. else {
  932. throw wrapper.insertObjectIncompatible() ;
  933. }
  934. } catch ( Exception ex ) {
  935. throw wrapper.insertObjectFailed(ex) ;
  936. }
  937. isInitialized = true;
  938. }
  939. /**
  940. * See the description of the <a href="#anyOps">general Any operations.</a>
  941. */
  942. public org.omg.CORBA.Object extract_Object()
  943. {
  944. //debug.log ("extract_Object");
  945. if (!isInitialized)
  946. throw wrapper.extractNotInitialized() ;
  947. // Check if the object contained here is of the type in typeCode
  948. org.omg.CORBA.Object obj = null;
  949. try {
  950. obj = (org.omg.CORBA.Object) object;
  951. if (typeCode.id().equals("IDL:omg.org/CORBA/Object:1.0") || obj._is_a(typeCode.id())) {
  952. return obj;
  953. } else {
  954. throw wrapper.extractObjectIncompatible() ;
  955. }
  956. } catch ( Exception ex ) {
  957. throw wrapper.extractObjectFailed(ex);
  958. }
  959. }
  960. /**
  961. * See the description of the <a href="#anyOps">general Any operations.</a>
  962. */
  963. public void insert_TypeCode(TypeCode tc)
  964. {
  965. //debug.log ("insert_TypeCode");
  966. typeCode = orb.get_primitive_tc(TCKind._tk_TypeCode);
  967. object = tc;
  968. isInitialized = true;
  969. }
  970. /**
  971. * See the description of the <a href="#anyOps">general Any operations.</a>
  972. */
  973. public TypeCode extract_TypeCode()
  974. {
  975. //debug.log ("extract_TypeCode");
  976. checkExtractBadOperation( TCKind._tk_TypeCode ) ;
  977. return (TypeCode)object;
  978. }
  979. /**
  980. * @deprecated
  981. */
  982. @Deprecated
  983. public void insert_Principal(Principal p)
  984. {
  985. typeCode = orb.get_primitive_tc(TCKind._tk_Principal);
  986. object = p;
  987. isInitialized = true;
  988. }
  989. /**
  990. * @deprecated
  991. */
  992. @Deprecated
  993. public Principal extract_Principal()
  994. {
  995. checkExtractBadOperation( TCKind._tk_Principal ) ;
  996. return (Principal)object;
  997. }
  998. /**
  999. * Note that the Serializable really should be an IDLEntity of
  1000. * some kind. It shouldn't just be an RMI-IIOP type. Currently,
  1001. * we accept and will produce RMI repIds with the latest
  1002. * calculations if given a non-IDLEntity Serializable.
  1003. */
  1004. public Serializable extract_Value()
  1005. {
  1006. //debug.log ("extract_Value");
  1007. checkExtractBadOperationList( new int[] { TCKind._tk_value,
  1008. TCKind._tk_value_box, TCKind._tk_abstract_interface } ) ;
  1009. return (Serializable)object;
  1010. }
  1011. public void insert_Value(Serializable v)
  1012. {
  1013. //debug.log ("insert_Value");
  1014. object = v;
  1015. TypeCode tc;
  1016. if ( v == null ) {
  1017. tc = orb.get_primitive_tc (TCKind.tk_value);
  1018. } else {
  1019. // See note in getPrimitiveTypeCodeForClass. We
  1020. // have to use the latest type code fixes in this
  1021. // case since there is no way to know what ORB will
  1022. // actually send this Any. In RMI-IIOP, when using
  1023. // Util.writeAny, we can do the versioning correctly,
  1024. // and use the insert_Value(Serializable, TypeCode)
  1025. // method.
  1026. //
  1027. // The ORB singleton uses the latest version.
  1028. tc = createTypeCodeForClass (v.getClass(), (ORB)ORB.init());
  1029. }
  1030. typeCode = TypeCodeImpl.convertToNative(orb, tc);
  1031. isInitialized = true;
  1032. }
  1033. public void insert_Value(Serializable v, org.omg.CORBA.TypeCode t)
  1034. {
  1035. //debug.log ("insert_Value2");
  1036. object = v;
  1037. typeCode = TypeCodeImpl.convertToNative(orb, t);
  1038. isInitialized = true;
  1039. }
  1040. public void insert_fixed(java.math.BigDecimal value) {
  1041. typeCode = TypeCodeImpl.convertToNative(orb,
  1042. orb.create_fixed_tc(TypeCodeImpl.digits(value), TypeCodeImpl.scale(value)));
  1043. object = value;
  1044. isInitialized = true;
  1045. }
  1046. public void insert_fixed(java.math.BigDecimal value, org.omg.CORBA.TypeCode type)
  1047. {
  1048. try {
  1049. if (TypeCodeImpl.digits(value) > type.fixed_digits() ||
  1050. TypeCodeImpl.scale(value) > type.fixed_scale())
  1051. {
  1052. throw wrapper.fixedNotMatch() ;
  1053. }
  1054. } catch (org.omg.CORBA.TypeCodePackage.BadKind bk) {
  1055. // type isn't even of kind fixed
  1056. throw wrapper.fixedBadTypecode( bk ) ;
  1057. }
  1058. typeCode = TypeCodeImpl.convertToNative(orb, type);
  1059. object = value;
  1060. isInitialized = true;
  1061. }
  1062. public java.math.BigDecimal extract_fixed() {
  1063. checkExtractBadOperation( TCKind._tk_fixed ) ;
  1064. return (BigDecimal)object;
  1065. }
  1066. /**
  1067. * Utility method for insert_Value and Util.writeAny.
  1068. *
  1069. * The ORB passed in should have the desired ORBVersion. It
  1070. * is used to generate the type codes.
  1071. */
  1072. public TypeCode createTypeCodeForClass (java.lang.Class c, ORB tcORB)
  1073. {
  1074. // Look in the cache first
  1075. TypeCodeImpl classTC = tcORB.getTypeCodeForClass(c);
  1076. if (classTC != null)
  1077. return classTC;
  1078. // All cases need to be able to create repository IDs.
  1079. //
  1080. // See bug 4391648 for more info about the tcORB in this
  1081. // case.
  1082. RepositoryIdStrings repStrs
  1083. = RepositoryIdFactory.getRepIdStringsFactory(tcORB);
  1084. // Assertion: c instanceof Serializable?
  1085. if ( c.isArray() ) {
  1086. // Arrays - may recurse for multi-dimensional arrays
  1087. Class componentClass = c.getComponentType();
  1088. TypeCode embeddedType;
  1089. if ( componentClass.isPrimitive() ) {
  1090. embeddedType = getPrimitiveTypeCodeForClass(componentClass,
  1091. tcORB);
  1092. } else {
  1093. embeddedType = createTypeCodeForClass (componentClass,
  1094. tcORB);
  1095. }
  1096. TypeCode t = tcORB.create_sequence_tc (0, embeddedType);
  1097. String id = repStrs.createForJavaType(c);
  1098. return tcORB.create_value_box_tc (id, "Sequence", t);
  1099. } else if ( c == java.lang.String.class ) {
  1100. // Strings
  1101. TypeCode t = tcORB.create_string_tc (0);
  1102. String id = repStrs.createForJavaType(c);
  1103. return tcORB.create_value_box_tc (id, "StringValue", t);
  1104. }
  1105. // Anything else
  1106. // We know that this is a TypeCodeImpl since it is our ORB
  1107. classTC = (TypeCodeImpl)ValueUtility.createTypeCodeForClass(
  1108. tcORB, c, ORBUtility.createValueHandler(tcORB));
  1109. // Intruct classTC to store its buffer
  1110. classTC.setCaching(true);
  1111. // Update the cache
  1112. tcORB.setTypeCodeForClass(c, classTC);
  1113. return classTC;
  1114. }
  1115. /**
  1116. * It looks like this was copied from io.ValueUtility at some
  1117. * point.
  1118. *
  1119. * It's used by createTypeCodeForClass. The tcORB passed in
  1120. * should have the desired ORB version, and is used to
  1121. * create the type codes.
  1122. */
  1123. private TypeCode getPrimitiveTypeCodeForClass (Class c, ORB tcORB)
  1124. {
  1125. //debug.log ("getPrimitiveTypeCodeForClass");
  1126. if (c == Integer.TYPE) {
  1127. return tcORB.get_primitive_tc (TCKind.tk_long);
  1128. } else if (c == Byte.TYPE) {
  1129. return tcORB.get_primitive_tc (TCKind.tk_octet);
  1130. } else if (c == Long.TYPE) {
  1131. return tcORB.get_primitive_tc (TCKind.tk_longlong);
  1132. } else if (c == Float.TYPE) {
  1133. return tcORB.get_primitive_tc (TCKind.tk_float);
  1134. } else if (c == Double.TYPE) {
  1135. return tcORB.get_primitive_tc (TCKind.tk_double);
  1136. } else if (c == Short.TYPE) {
  1137. return tcORB.get_primitive_tc (TCKind.tk_short);
  1138. } else if (c == Character.TYPE) {
  1139. // For Merlin or later JDKs, or for foreign ORBs,
  1140. // we correctly say that a Java char maps to a
  1141. // CORBA wchar. For backwards compatibility
  1142. // with our older ORBs, we say it maps to a
  1143. // CORBA char. This is only used in RMI-IIOP
  1144. // in our javax.rmi.CORBA.Util delegate's
  1145. // writeAny method. In Java IDL, there's no way
  1146. // to know the ORB version that the Any will be
  1147. // sent out with -- it could be different than
  1148. // the one used to create the Any -- so we use the
  1149. // most recent version (see insert_Value).
  1150. if (ORBVersionFactory.getFOREIGN().compareTo(tcORB.getORBVersion()) == 0 ||
  1151. ORBVersionFactory.getNEWER().compareTo(tcORB.getORBVersion()) <= 0)
  1152. return tcORB.get_primitive_tc(TCKind.tk_wchar);
  1153. else
  1154. return tcORB.get_primitive_tc(TCKind.tk_char);
  1155. } else if (c == Boolean.TYPE) {
  1156. return tcORB.get_primitive_tc (TCKind.tk_boolean);
  1157. } else {
  1158. // _REVISIT_ Not sure if this is right.
  1159. return tcORB.get_primitive_tc (TCKind.tk_any);
  1160. }
  1161. }
  1162. // Extracts a member value according to the given TypeCode from the given complex Any
  1163. // (at the Anys current internal stream position, consuming the anys stream on the way)
  1164. // and returns it wrapped into a new Any
  1165. public Any extractAny(TypeCode memberType, ORB orb) {
  1166. Any returnValue = orb.create_any();
  1167. OutputStream out = returnValue.create_output_stream();
  1168. TypeCodeImpl.convertToNative(orb, memberType).copy((InputStream)stream, out);
  1169. returnValue.read_value(out.create_input_stream(), memberType);
  1170. return returnValue;
  1171. }
  1172. // This method could very well be moved into TypeCodeImpl or a common utility class,
  1173. // but is has to be in this package.
  1174. static public Any extractAnyFromStream(TypeCode memberType, InputStream input, ORB orb) {
  1175. Any returnValue = orb.create_any();
  1176. OutputStream out = returnValue.create_output_stream();
  1177. TypeCodeImpl.convertToNative(orb, memberType).copy(input, out);
  1178. returnValue.read_value(out.create_input_stream(), memberType);
  1179. return returnValue;
  1180. }
  1181. // There is no other way for DynAnys to find out whether the Any is initialized.
  1182. public boolean isInitialized() {
  1183. return isInitialized;
  1184. }
  1185. }