package org.jacorb.orb.giop; /* * JacORB - a free Java ORB * * Copyright (C) 1997-2014 Gerald Brose / The JacORB Team. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.jacorb.orb.CDROutputStream; import org.jacorb.orb.CodeSet; import org.jacorb.orb.miop.MIOPProfile; import org.jacorb.orb.miop.MulticastUtil; import org.jacorb.util.Time; import org.omg.CONV_FRAME.CodeSetContext; import org.omg.CONV_FRAME.CodeSetContextHelper; import org.omg.CORBA.MARSHAL; import org.omg.GIOP.PrincipalHelper; import org.omg.GIOP.MsgType_1_1; import org.omg.GIOP.TargetAddress; import org.omg.GIOP.TargetAddressHelper; import org.omg.IOP.INVOCATION_POLICIES; import org.omg.IOP.ServiceContext; import org.omg.IOP.ServiceContextListHelper; import org.omg.IOP.TAG_CODE_SETS; import org.omg.IOP.TAG_UIPMC; import org.omg.IOP.TaggedProfile; import org.omg.MIOP.UIPMC_ProfileBodyHelper; import org.omg.Messaging.PolicyValue; import org.omg.Messaging.PolicyValueSeqHelper; import org.omg.Messaging.REPLY_END_TIME_POLICY_TYPE; import org.omg.Messaging.REQUEST_END_TIME_POLICY_TYPE; import org.omg.Messaging.REQUEST_START_TIME_POLICY_TYPE; import org.omg.Messaging.SYNC_NONE; import org.omg.Messaging.SYNC_WITH_SERVER; import org.omg.Messaging.SYNC_WITH_TARGET; import org.omg.Messaging.SYNC_WITH_TRANSPORT; import org.omg.TimeBase.UtcT; /** * @author Gerald Brose, FU Berlin 1999 */ public class RequestOutputStream extends ServiceContextTransportingOutputStream { private final static byte[] principal = new byte[ 0 ]; private final static byte[] reserved = new byte[ 3 ]; private final int request_id; private final boolean response_expected; private final short syncScope; private final String operation; /** * Absolute time after which this request may be delivered to its target. * (CORBA 3.0, 22.2.4.1) */ private final UtcT requestStartTime; /** * Absolute time after which this request may no longer be delivered * to its target. (CORBA 3.0, 22.2.4.2/5) */ private final UtcT requestEndTime; /** * Absolute time after which a reply may no longer be obtained * or returned to the client. (CORBA 3.0, 22.2.4.4/6) */ private final UtcT replyEndTime; private org.jacorb.orb.dii.Request request = null; private final ClientConnection connection; private final byte[] object_key; /** * Copy constructor for <code>RequestOutputStream</code> used for SYNC_SCOPE NONE. * * @param other a <code>RequestOutputStream</code> value */ public RequestOutputStream( RequestOutputStream other) { super(other.orb); this.object_key = other.object_key; this.request_id = other.request_id; this.response_expected = other.response_expected; this.syncScope = other.syncScope; this.operation = other.operation; this.connection = other.connection; this.requestStartTime = other.requestStartTime; this.requestEndTime = other.requestEndTime; this.replyEndTime = other.replyEndTime; this.contexts = other.contexts; this.header_end = other.header_end; this.header_padding = other.header_padding; this.giop_minor = other.giop_minor; byte[] copy = other.getBufferCopy(); write_octet_array (copy, 0, copy.length); } public RequestOutputStream( org.jacorb.orb.ORB orb, ClientConnection connection, int request_id, String operation, boolean response_expected, short syncScope, UtcT requestStartTime, UtcT requestEndTime, UtcT replyEndTime, byte[] object_key, int giop_minor ) { super(orb); setGIOPMinor( giop_minor ); this.object_key = object_key; this.request_id = request_id; this.response_expected = response_expected; this.syncScope = syncScope; this.operation = operation; this.connection = connection; this.requestStartTime = requestStartTime; this.requestEndTime = requestEndTime; this.replyEndTime = replyEndTime; if (requestStartTime != null || requestEndTime != null || replyEndTime != null) { addServiceContext (createInvocationPolicies()); } writeGIOPMsgHeader( MsgType_1_1._Request, giop_minor ); boolean isMIOP = (connection != null && connection.getRegisteredProfile () instanceof MIOPProfile); switch( giop_minor ) { case 0 : case 1 : { //GIOP 1.0/1.1 inlined ServiceContextListHelper.write( this , Messages.service_context ); write_ulong( request_id); write_boolean( response_expected ); if (giop_minor == 1) { write_octet_array( reserved,0,3 ); } if (isMIOP) { write_char_array (MulticastUtil.MAGIC, 0, MulticastUtil.MAGIC.length); write_long (TAG_UIPMC.value); this.beginEncapsulation (); UIPMC_ProfileBodyHelper.write (this, ((MIOPProfile)connection.getRegisteredProfile ()).getUIPMCProfile ()); this.endEncapsulation (); } else { write_long( object_key.length ); write_octet_array( object_key, 0, object_key.length); } write_string( operation); PrincipalHelper.write( this, principal); break; } case 2 : { //GIOP 1.2 TargetAddress addr = new TargetAddress(); if (isMIOP) { TaggedProfile uipmc = new TaggedProfile (org.omg.IOP.TAG_UIPMC.value, MulticastUtil.getEncapsulatedUIPMCProfile (orb, connection)); addr.profile (uipmc); } else { addr.object_key( object_key ); } // inlined RequestHeader_1_2Helper.write method write_ulong( request_id); if (response_expected) { write_octet ((byte)0x03); } else { switch (syncScope) { case SYNC_NONE.value: // fallthrough case SYNC_WITH_TRANSPORT.value: { write_octet ((byte)0x00); break; } case SYNC_WITH_SERVER.value: { write_octet ((byte)0x01); break; } case SYNC_WITH_TARGET.value: { write_octet ((byte)0x03); break; } default: { throw new MARSHAL ("Invalid SYNC_SCOPE: " + syncScope); } } } write_octet_array( reserved,0,3 ); TargetAddressHelper.write( this, addr ); write_string( operation ); ServiceContextListHelper.write( this, Messages.service_context ); markHeaderEnd(); //use padding if GIOP minor == 2 break; } default : { throw new MARSHAL( "Unknown GIOP minor: " + giop_minor ); } } } public int requestId() { return request_id; } public boolean response_expected() { return response_expected; } public short syncScope() { return syncScope; } public String operation() { return operation; } public UtcT getReplyEndTime() { return replyEndTime; } public void setRequest(org.jacorb.orb.dii.Request request) { this.request = request; } public org.jacorb.orb.dii.Request getRequest() { return request; } public ClientConnection getConnection() { return connection; } /** * Overridden to add a codeset service context if this * is the first request on the connection. */ public void write_to(GIOPConnection conn) throws IOException { if (!conn.isTCSNegotiated()) { // encapsulate context addServiceContext (createCodesetContext ( conn.getTCS(), conn.getTCSW())); conn.markTCSNegotiated(); } super.write_to(conn); } private ServiceContext createCodesetContext( CodeSet tcs, CodeSet tcsw ) { // encapsulate context final CDROutputStream os = new CDROutputStream( orb ); try { os.beginEncapsulatedArray(); CodeSetContextHelper.write( os, new CodeSetContext( tcs.getId(), tcsw.getId() )); return new ServiceContext( TAG_CODE_SETS.value, os.getBufferCopy() ); } finally { os.close(); } } /** * Returns the timing policies for this request as an array * of PolicyValues that can be propagated in a ServiceContext. */ private PolicyValue[] getTimingPolicyValues() { List list = new ArrayList(); if (requestStartTime != null) { list.add (new PolicyValue (REQUEST_START_TIME_POLICY_TYPE.value, Time.toCDR (requestStartTime))); } if (requestEndTime != null) { list.add (new PolicyValue (REQUEST_END_TIME_POLICY_TYPE.value, Time.toCDR (requestEndTime))); } if (replyEndTime != null) { list.add (new PolicyValue (REPLY_END_TIME_POLICY_TYPE.value, Time.toCDR (replyEndTime))); } return (PolicyValue[])list.toArray (new PolicyValue[list.size()]); } private ServiceContext createInvocationPolicies() { final CDROutputStream out = new CDROutputStream( orb ); try { out.beginEncapsulatedArray(); PolicyValueSeqHelper.write(out, getTimingPolicyValues()); return new ServiceContext (INVOCATION_POLICIES.value, out.getBufferCopy()); } finally { out.close(); } } }