Source for gnu.CORBA.ResponseHandlerImpl

   1: /* ResponseHandlerImpl.java --
   2:    Copyright (C) 2005 Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: 
  39: package gnu.CORBA;
  40: 
  41: import gnu.CORBA.CDR.BufferedCdrOutput;
  42: import gnu.CORBA.GIOP.MessageHeader;
  43: import gnu.CORBA.GIOP.ReplyHeader;
  44: import gnu.CORBA.GIOP.RequestHeader;
  45: import gnu.CORBA.GIOP.CodeSetServiceContext;
  46: 
  47: import org.omg.CORBA.ORB;
  48: import org.omg.CORBA.portable.OutputStream;
  49: import org.omg.CORBA.portable.ResponseHandler;
  50: 
  51: /**
  52:  * Provides the CDR output streams for writing the response to the given buffer.
  53:  *
  54:  * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
  55:  */
  56: public class ResponseHandlerImpl
  57:   implements ResponseHandler
  58: {
  59:   /**
  60:    * The message header. This field is used to compute the size and alignments.
  61:    * It is, however, never directly written to the buffer stream.
  62:    */
  63:   public final MessageHeader message_header;
  64: 
  65:   /**
  66:    * The associated orb.
  67:    */
  68:   public final ORB orb;
  69: 
  70:   /**
  71:    * The reply header.
  72:    */
  73:   public final ReplyHeader reply_header;
  74: 
  75:   /**
  76:    * The request header.
  77:    */
  78:   public final RequestHeader request_header;
  79: 
  80:   /**
  81:    * True if the stream was obtained by invoking {@link #createExceptionReply()},
  82:    * false otherwise.
  83:    */
  84:   private boolean exceptionReply;
  85: 
  86:   /**
  87:    * The buffer to write into.
  88:    */
  89:   private BufferedCdrOutput buffer;
  90: 
  91:   /**
  92:    * Create a new buffered response handler that uses the given message headers.
  93:    * The headers are used to compute sizes and check the versions. They are not
  94:    * written into a stream inside this class.
  95:    *
  96:    * @param m_header a message header.
  97:    * @param r_header a reply header.
  98:    */
  99:   ResponseHandlerImpl(ORB an_orb, MessageHeader m_header,
 100:                           ReplyHeader r_header, RequestHeader rq_header)
 101:   {
 102:     message_header = m_header;
 103:     reply_header = r_header;
 104:     request_header = rq_header;
 105:     orb = an_orb;
 106:     prepareStream();
 107:   }
 108: 
 109:   /**
 110:    * Get an output stream for providing details about the exception. Before
 111:    * returning the stream, the handler automatically writes the message header
 112:    * and the reply about exception header, but not the message header.
 113:    *
 114:    * @return the stream to write exception details into.
 115:    */
 116:   public OutputStream createExceptionReply()
 117:   {
 118:     exceptionReply = true;
 119:     prepareStream();
 120:     return buffer;
 121:   }
 122: 
 123:   /**
 124:    * Get an output stream for writing a regular reply (not an exception).
 125:    *
 126:    * Before returning the stream, the handler automatically writes the regular
 127:    * reply header, but not the message header.
 128:    *
 129:    * @return the output stream for writing a regular reply.
 130:    */
 131:   public OutputStream createReply()
 132:   {
 133:     exceptionReply = false;
 134:     prepareStream();
 135:     reply_header.reply_status = ReplyHeader.NO_EXCEPTION;
 136:     return buffer;
 137:   }
 138: 
 139:   /**
 140:    * Get the buffer, normally containing the written reply. The reply includes
 141:    * the reply header (or the exception header) but does not include the message
 142:    * header.
 143:    *
 144:    * The stream buffer can also be empty if no data have been written into
 145:    * streams, returned by {@link #createReply()} or
 146:    * {@link #createExceptionReply()}.
 147:    *
 148:    * @return the CDR output stream, containing the written output.
 149:    */
 150:   public BufferedCdrOutput getBuffer()
 151:   {
 152:     return buffer;
 153:   }
 154: 
 155:   /**
 156:    * True if the stream was obtained by invoking {@link #createExceptionReply()},
 157:    * false otherwise (usually no-exception reply).
 158:    */
 159:   public boolean isExceptionReply()
 160:   {
 161:     return exceptionReply;
 162:   }
 163: 
 164:   /**
 165:    * Compute the header offset, set the correct version number and codeset.
 166:    */
 167:   private void prepareStream()
 168:   {
 169:     buffer = new BufferedCdrOutput();
 170:     buffer.setOrb(orb);
 171:     buffer.setVersion(message_header.version);
 172:     buffer.setCodeSet(CodeSetServiceContext.find(reply_header.service_context));
 173: 
 174:     // Since 1.2, the data section is always aligned on the 8 byte boundary.
 175:     // In older versions, it is necessary to set the offset correctly.
 176:     if (message_header.version.until_inclusive(1, 1))
 177:       {
 178:         buffer.setOffset(message_header.getHeaderSize());
 179: 
 180:         // Get the position after the reply header would be written.
 181:         reply_header.write(buffer);
 182: 
 183:         int new_offset = message_header.getHeaderSize() + buffer.buffer.size();
 184: 
 185:         buffer.buffer.reset();
 186:         buffer.setOffset(new_offset);
 187:       }
 188:   }
 189: }