1. /*
  2. * @(#)CDROutputObject.java 1.54 04/06/21
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package com.sun.corba.se.impl.encoding;
  8. import java.io.IOException;
  9. import java.nio.ByteBuffer;
  10. import org.omg.CORBA.Any;
  11. import org.omg.CORBA.Principal;
  12. import org.omg.CORBA.TypeCode;
  13. import org.omg.CORBA.portable.InputStream;
  14. import com.sun.corba.se.pept.encoding.OutputObject;
  15. import com.sun.corba.se.pept.protocol.MessageMediator;
  16. import com.sun.corba.se.spi.encoding.CorbaOutputObject ;
  17. import com.sun.corba.se.spi.ior.iiop.GIOPVersion;
  18. import com.sun.corba.se.spi.orb.ORB;
  19. import com.sun.corba.se.spi.protocol.CorbaMessageMediator;
  20. import com.sun.corba.se.pept.transport.ByteBufferPool;
  21. import com.sun.corba.se.spi.transport.CorbaConnection;
  22. import com.sun.corba.se.spi.logging.CORBALogDomains;
  23. import com.sun.corba.se.spi.servicecontext.ServiceContexts;
  24. import com.sun.corba.se.impl.encoding.BufferManagerFactory;
  25. import com.sun.corba.se.impl.encoding.ByteBufferWithInfo;
  26. import com.sun.corba.se.impl.encoding.CDROutputStream;
  27. import com.sun.corba.se.impl.encoding.CDROutputStream_1_0;
  28. import com.sun.corba.se.impl.encoding.CodeSetConversion;
  29. import com.sun.corba.se.impl.encoding.CodeSetComponentInfo;
  30. import com.sun.corba.se.impl.encoding.OSFCodeSetRegistry;
  31. import com.sun.corba.se.impl.orbutil.ORBUtility;
  32. import com.sun.corba.se.impl.protocol.giopmsgheaders.Message;
  33. import com.sun.corba.se.impl.protocol.giopmsgheaders.MessageBase;
  34. import com.sun.corba.se.impl.logging.ORBUtilSystemException;
  35. import com.sun.corba.se.impl.logging.OMGSystemException;
  36. /**
  37. * @author Harold Carr
  38. */
  39. public class CDROutputObject extends CorbaOutputObject
  40. {
  41. private Message header;
  42. private ORB orb;
  43. private ORBUtilSystemException wrapper;
  44. private OMGSystemException omgWrapper;
  45. // REVISIT - only used on sendCancelRequest.
  46. private CorbaConnection connection;
  47. private CDROutputObject(
  48. ORB orb, GIOPVersion giopVersion, Message header,
  49. BufferManagerWrite manager, byte streamFormatVersion,
  50. CorbaMessageMediator mediator)
  51. {
  52. super(orb, giopVersion, header.getEncodingVersion(),
  53. false, manager, streamFormatVersion,
  54. ((mediator != null && mediator.getConnection() != null) ?
  55. ((CorbaConnection)mediator.getConnection()).
  56. shouldUseDirectByteBuffers() : false));
  57. this.header = header;
  58. this.orb = orb;
  59. this.wrapper = ORBUtilSystemException.get( orb, CORBALogDomains.RPC_ENCODING ) ;
  60. this.omgWrapper = OMGSystemException.get( orb, CORBALogDomains.RPC_ENCODING ) ;
  61. getBufferManager().setOutputObject(this);
  62. this.corbaMessageMediator = mediator;
  63. }
  64. public CDROutputObject(ORB orb,
  65. MessageMediator messageMediator,
  66. Message header,
  67. byte streamFormatVersion)
  68. {
  69. this(
  70. orb,
  71. ((CorbaMessageMediator)messageMediator).getGIOPVersion(),
  72. header,
  73. BufferManagerFactory.newBufferManagerWrite(
  74. ((CorbaMessageMediator)messageMediator).getGIOPVersion(),
  75. header.getEncodingVersion(),
  76. orb),
  77. streamFormatVersion,
  78. (CorbaMessageMediator)messageMediator);
  79. }
  80. // NOTE:
  81. // Used in SharedCDR (i.e., must be grow).
  82. // Used in msgtypes test.
  83. public CDROutputObject(ORB orb,
  84. MessageMediator messageMediator,
  85. Message header,
  86. byte streamFormatVersion,
  87. int strategy)
  88. {
  89. this(
  90. orb,
  91. ((CorbaMessageMediator)messageMediator).getGIOPVersion(),
  92. header,
  93. BufferManagerFactory.
  94. newBufferManagerWrite(strategy,
  95. header.getEncodingVersion(),
  96. orb),
  97. streamFormatVersion,
  98. (CorbaMessageMediator)messageMediator);
  99. }
  100. // REVISIT
  101. // Used on sendCancelRequest.
  102. // Used for needs addressing mode.
  103. public CDROutputObject(ORB orb, CorbaMessageMediator mediator,
  104. GIOPVersion giopVersion,
  105. CorbaConnection connection, Message header,
  106. byte streamFormatVersion)
  107. {
  108. this(
  109. orb,
  110. giopVersion,
  111. header,
  112. BufferManagerFactory.
  113. newBufferManagerWrite(giopVersion,
  114. header.getEncodingVersion(),
  115. orb),
  116. streamFormatVersion,
  117. mediator);
  118. this.connection = connection ;
  119. }
  120. // XREVISIT
  121. // Header should only be in message mediator.
  122. // Another possibility: merge header and message mediator.
  123. // REVISIT - make protected once all encoding together
  124. public Message getMessageHeader() {
  125. return header;
  126. }
  127. public final void finishSendingMessage() {
  128. getBufferManager().sendMessage();
  129. }
  130. /**
  131. * Write the contents of the CDROutputStream to the specified
  132. * output stream. Has the side-effect of pushing any current
  133. * Message onto the Message list.
  134. * @param s The output stream to write to.
  135. */
  136. public void writeTo(CorbaConnection connection)
  137. throws java.io.IOException
  138. {
  139. //
  140. // Update the GIOP MessageHeader size field.
  141. //
  142. ByteBufferWithInfo bbwi = getByteBufferWithInfo();
  143. getMessageHeader().setSize(bbwi.byteBuffer, bbwi.getSize());
  144. if (orb() != null) {
  145. if (((ORB)orb()).transportDebugFlag) {
  146. dprint(".writeTo: " + connection);
  147. }
  148. if (((ORB)orb()).giopDebugFlag) {
  149. CDROutputStream_1_0.printBuffer(bbwi);
  150. }
  151. }
  152. bbwi.byteBuffer.position(0).limit(bbwi.getSize());
  153. connection.write(bbwi.byteBuffer);
  154. }
  155. /** overrides create_input_stream from CDROutputStream */
  156. public org.omg.CORBA.portable.InputStream create_input_stream()
  157. {
  158. // XREVISIT
  159. return null;
  160. //return new XIIOPInputStream(orb(), getByteBuffer(), getIndex(),
  161. //isLittleEndian(), getMessageHeader(), conn);
  162. }
  163. public CorbaConnection getConnection()
  164. {
  165. // REVISIT - only set when doing sendCancelRequest.
  166. if (connection != null) {
  167. return connection;
  168. }
  169. return (CorbaConnection) corbaMessageMediator.getConnection();
  170. }
  171. // XREVISIT - If CDROutputObject doesn't live in the iiop
  172. // package, it will need this, here, to give package access
  173. // to xgiop.
  174. // REVISIT - make protected once all encoding together
  175. public final ByteBufferWithInfo getByteBufferWithInfo() {
  176. return super.getByteBufferWithInfo();
  177. }
  178. // REVISIT - make protected once all encoding together
  179. public final void setByteBufferWithInfo(ByteBufferWithInfo bbwi) {
  180. super.setByteBufferWithInfo(bbwi);
  181. }
  182. /**
  183. * Override the default CDR factory behavior to get the
  184. * negotiated code sets from the connection.
  185. *
  186. * These are only called once per message, the first time needed.
  187. *
  188. * In the local case, there is no Connection, so use the
  189. * local code sets.
  190. */
  191. protected CodeSetConversion.CTBConverter createCharCTBConverter() {
  192. CodeSetComponentInfo.CodeSetContext codesets = getCodeSets();
  193. // If the connection doesn't have its negotiated
  194. // code sets by now, fall back on the defaults defined
  195. // in CDRInputStream.
  196. if (codesets == null)
  197. return super.createCharCTBConverter();
  198. OSFCodeSetRegistry.Entry charSet
  199. = OSFCodeSetRegistry.lookupEntry(codesets.getCharCodeSet());
  200. if (charSet == null)
  201. throw wrapper.unknownCodeset( charSet ) ;
  202. return CodeSetConversion.impl().getCTBConverter(charSet,
  203. isLittleEndian(),
  204. false);
  205. }
  206. protected CodeSetConversion.CTBConverter createWCharCTBConverter() {
  207. CodeSetComponentInfo.CodeSetContext codesets = getCodeSets();
  208. // If the connection doesn't have its negotiated
  209. // code sets by now, we have to throw an exception.
  210. // See CORBA formal 00-11-03 13.9.2.6.
  211. if (codesets == null) {
  212. if (getConnection().isServer())
  213. throw omgWrapper.noClientWcharCodesetCtx() ;
  214. else
  215. throw omgWrapper.noServerWcharCodesetCmp() ;
  216. }
  217. OSFCodeSetRegistry.Entry wcharSet
  218. = OSFCodeSetRegistry.lookupEntry(codesets.getWCharCodeSet());
  219. if (wcharSet == null)
  220. throw wrapper.unknownCodeset( wcharSet ) ;
  221. boolean useByteOrderMarkers
  222. = ((ORB)orb()).getORBData().useByteOrderMarkers();
  223. // With UTF-16:
  224. //
  225. // For GIOP 1.2, we can put byte order markers if we want to, and
  226. // use the default of big endian otherwise. (See issue 3405b)
  227. //
  228. // For GIOP 1.1, we don't use BOMs and use the endianness of
  229. // the stream.
  230. if (wcharSet == OSFCodeSetRegistry.UTF_16) {
  231. if (getGIOPVersion().equals(GIOPVersion.V1_2)) {
  232. return CodeSetConversion.impl().getCTBConverter(wcharSet,
  233. false,
  234. useByteOrderMarkers);
  235. }
  236. if (getGIOPVersion().equals(GIOPVersion.V1_1)) {
  237. return CodeSetConversion.impl().getCTBConverter(wcharSet,
  238. isLittleEndian(),
  239. false);
  240. }
  241. }
  242. // In the normal case, let the converter system handle it
  243. return CodeSetConversion.impl().getCTBConverter(wcharSet,
  244. isLittleEndian(),
  245. useByteOrderMarkers);
  246. }
  247. // If we're local and don't have a Connection, use the
  248. // local code sets, otherwise get them from the connection.
  249. // If the connection doesn't have negotiated code sets
  250. // yet, then we use ISO8859-1 for char/string and wchar/wstring
  251. // are illegal.
  252. private CodeSetComponentInfo.CodeSetContext getCodeSets() {
  253. if (getConnection() == null)
  254. return CodeSetComponentInfo.LOCAL_CODE_SETS;
  255. else
  256. return getConnection().getCodeSetContext();
  257. }
  258. protected void dprint(String msg)
  259. {
  260. ORBUtility.dprint("CDROutputObject", msg);
  261. }
  262. }
  263. // End of file.