001: package org.jacorb.orb.giop;
002:
003: /*
004: * JacORB - a free Java ORB
005: *
006: * Copyright (C) 1997-2004 Gerald Brose.
007: *
008: * This library is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU Library General Public
010: * License as published by the Free Software Foundation; either
011: * version 2 of the License, or (at your option) any later version.
012: *
013: * This library is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
016: * Library General Public License for more details.
017: *
018: * You should have received a copy of the GNU Library General Public
019: * License along with this library; if not, write to the Free
020: * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
021: */
022:
023: import java.io.IOException;
024: import java.util.ArrayList;
025: import java.util.List;
026:
027: import org.jacorb.orb.CDROutputStream;
028: import org.jacorb.util.Time;
029: import org.omg.CONV_FRAME.CodeSetContext;
030: import org.omg.CONV_FRAME.CodeSetContextHelper;
031: import org.omg.CORBA.MARSHAL;
032: import org.omg.CORBA.PrincipalHelper;
033: import org.omg.GIOP.MsgType_1_1;
034: import org.omg.GIOP.TargetAddress;
035: import org.omg.GIOP.TargetAddressHelper;
036: import org.omg.IOP.INVOCATION_POLICIES;
037: import org.omg.IOP.ServiceContext;
038: import org.omg.IOP.ServiceContextListHelper;
039: import org.omg.Messaging.PolicyValue;
040: import org.omg.Messaging.PolicyValueSeqHelper;
041: import org.omg.Messaging.REPLY_END_TIME_POLICY_TYPE;
042: import org.omg.Messaging.REQUEST_END_TIME_POLICY_TYPE;
043: import org.omg.Messaging.REQUEST_START_TIME_POLICY_TYPE;
044: import org.omg.Messaging.SYNC_NONE;
045: import org.omg.Messaging.SYNC_WITH_SERVER;
046: import org.omg.Messaging.SYNC_WITH_TARGET;
047: import org.omg.Messaging.SYNC_WITH_TRANSPORT;
048: import org.omg.TimeBase.UtcT;
049:
050: /**
051: * @author Gerald Brose, FU Berlin 1999
052: * @version $Id: RequestOutputStream.java,v 1.32 2006/07/26 11:05:21 nick.cross Exp $
053: */
054: public class RequestOutputStream extends
055: ServiceContextTransportingOutputStream {
056: private final static byte[] principal = new byte[0];
057: private final static byte[] reserved = new byte[3];
058:
059: private final int request_id;
060: private final boolean response_expected;
061: private final short syncScope;
062: private final String operation;
063:
064: /**
065: * Absolute time after which this request may be delivered to its target.
066: * (CORBA 3.0, 22.2.4.1)
067: */
068: private final UtcT requestStartTime;
069:
070: /**
071: * Absolute time after which this request may no longer be delivered
072: * to its target. (CORBA 3.0, 22.2.4.2/5)
073: */
074: private final UtcT requestEndTime;
075:
076: /**
077: * Absolute time after which a reply may no longer be obtained
078: * or returned to the client. (CORBA 3.0, 22.2.4.4/6)
079: */
080: private final UtcT replyEndTime;
081:
082: private org.jacorb.orb.dii.Request request = null;
083:
084: private final ClientConnection connection;
085:
086: public RequestOutputStream(org.jacorb.orb.ORB orb,
087: ClientConnection connection, int request_id,
088: String operation, boolean response_expected,
089: short syncScope, UtcT requestStartTime,
090: UtcT requestEndTime, UtcT replyEndTime, byte[] object_key,
091: int giop_minor) {
092: super (orb);
093:
094: setGIOPMinor(giop_minor);
095:
096: this .request_id = request_id;
097: this .response_expected = response_expected;
098: this .syncScope = syncScope;
099: this .operation = operation;
100: this .connection = connection;
101:
102: this .requestStartTime = requestStartTime;
103: this .requestEndTime = requestEndTime;
104: this .replyEndTime = replyEndTime;
105:
106: if (requestStartTime != null || requestEndTime != null
107: || replyEndTime != null) {
108: addServiceContext(createInvocationPolicies());
109: }
110:
111: writeGIOPMsgHeader(MsgType_1_1._Request, giop_minor);
112:
113: switch (giop_minor) {
114: case 0: {
115: // GIOP 1.0 inlining
116: ServiceContextListHelper.write(this ,
117: Messages.service_context);
118: write_ulong(request_id);
119: write_boolean(response_expected);
120: write_long(object_key.length);
121: write_octet_array(object_key, 0, object_key.length);
122: write_string(operation);
123: PrincipalHelper.write(this , principal);
124:
125: break;
126: }
127: case 1: {
128: //GIOP 1.1
129: ServiceContextListHelper.write(this ,
130: Messages.service_context);
131: write_ulong(request_id);
132: write_boolean(response_expected);
133: write_long(object_key.length);
134: write_octet_array(object_key, 0, object_key.length);
135: write_string(operation);
136: PrincipalHelper.write(this , principal);
137:
138: break;
139: }
140: case 2: {
141: //GIOP 1.2
142: TargetAddress addr = new TargetAddress();
143: addr.object_key(object_key);
144:
145: // inlined RequestHeader_1_2Helper.write method
146:
147: write_ulong(request_id);
148: if (response_expected) {
149: write_octet((byte) 0x03);
150: } else {
151: switch (syncScope) {
152: case SYNC_NONE.value:
153: case SYNC_WITH_TRANSPORT.value:
154: write_octet((byte) 0x00);
155: break;
156: case SYNC_WITH_SERVER.value:
157: write_octet((byte) 0x01);
158: break;
159: case SYNC_WITH_TARGET.value:
160: write_octet((byte) 0x03);
161: break;
162: default:
163: throw new MARSHAL("Invalid SYNC_SCOPE: "
164: + syncScope);
165: }
166: }
167:
168: write_octet_array(reserved, 0, 3);
169: TargetAddressHelper.write(this , addr);
170: write_string(operation);
171: ServiceContextListHelper.write(this ,
172: Messages.service_context);
173:
174: markHeaderEnd(); //use padding if GIOP minor == 2
175:
176: break;
177: }
178: default: {
179: throw new MARSHAL("Unknown GIOP minor: " + giop_minor);
180: }
181: }
182: }
183:
184: public int requestId() {
185: return request_id;
186: }
187:
188: public boolean response_expected() {
189: return response_expected;
190: }
191:
192: public short syncScope() {
193: return syncScope;
194: }
195:
196: public String operation() {
197: return operation;
198: }
199:
200: public UtcT getReplyEndTime() {
201: return replyEndTime;
202: }
203:
204: public void setRequest(org.jacorb.orb.dii.Request request) {
205: this .request = request;
206: }
207:
208: public org.jacorb.orb.dii.Request getRequest() {
209: return request;
210: }
211:
212: public ClientConnection getConnection() {
213: return connection;
214: }
215:
216: /**
217: * Overridden to add a codeset service context if this
218: * is the first request on the connection.
219: */
220: public void write_to(GIOPConnection conn) throws IOException {
221: if (!conn.isTCSNegotiated()) {
222: // encapsulate context
223: addServiceContext(CodeSet.createCodesetContext(conn
224: .getTCS(), conn.getTCSW()));
225:
226: conn.markTCSNegotiated();
227: }
228: super .write_to(conn);
229: }
230:
231: /**
232: * Returns the timing policies for this request as an array
233: * of PolicyValues that can be propagated in a ServiceContext.
234: */
235: private PolicyValue[] getTimingPolicyValues() {
236: List list = new ArrayList();
237: if (requestStartTime != null) {
238: list.add(new PolicyValue(
239: REQUEST_START_TIME_POLICY_TYPE.value, Time
240: .toCDR(requestStartTime)));
241: }
242: if (requestEndTime != null) {
243: list.add(new PolicyValue(
244: REQUEST_END_TIME_POLICY_TYPE.value, Time
245: .toCDR(requestEndTime)));
246: }
247: if (replyEndTime != null) {
248: list.add(new PolicyValue(REPLY_END_TIME_POLICY_TYPE.value,
249: Time.toCDR(replyEndTime)));
250: }
251: return (PolicyValue[]) list
252: .toArray(new PolicyValue[list.size()]);
253: }
254:
255: private ServiceContext createInvocationPolicies() {
256: final CDROutputStream out = new CDROutputStream();
257:
258: try {
259: out.beginEncapsulatedArray();
260: PolicyValueSeqHelper.write(out, getTimingPolicyValues());
261: return new ServiceContext(INVOCATION_POLICIES.value, out
262: .getBufferCopy());
263: } finally {
264: out.close();
265: }
266: }
267: }
|