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