CVS: beepcore-java/src/org/beepcore/beep/core RequestHandler.java,NONE,1.1 Channel.java,1.32,1.33 ChannelImpl.java,1.6,1.7 Session.java,1.35,1.36 SessionImpl.java,1.7,1.8 TuningResetException.java,1.2,1.3 ThreadedMessageListener.java,1.2,NONE

Huston Franklin <[email protected]> Tue, 10 Jun 2003 11:59:55 -0700
Newsgroups gmane.network.beep.beepcore.java.cvs
Message-ID <[email protected]>
Update of /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/core
In directory sc8-pr-cvs1:/tmp/cvs-serv21972/src/org/beepcore/beep/core

Modified Files:
	Channel.java ChannelImpl.java Session.java SessionImpl.java 
	TuningResetException.java 
Added Files:
	RequestHandler.java 
Removed Files:
	ThreadedMessageListener.java 
Log Message:
More interface cleanup, added RequestHandler to replace MessageListener.

--- NEW FILE: RequestHandler.java ---
/*
 * RequestHandler.java  $Revision: 1.1 $ $Date: 2003/06/10 18:59:19 $
 *
 * Copyright (c) 2003 Huston Franklin.  All rights reserved.
 *
 * The contents of this file are subject to the Blocks Public License (the
 * "License"); You may not use this file except in compliance with the License.
 *
 * You may obtain a copy of the License at http://www.beepcore.org/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 */
package org.beepcore.beep.core;

/**
 * This interface is used by profiles to receive MSG messages. This handler is
 * registered with a channel using the <code>setRequestHandler()</code> method.
 *
 * @author Huston Franklin
 * @version $Revision: 1.1 $, $Date: 2003/06/10 18:59:19 $
 *
 */
public interface RequestHandler {
    /**
     * Called to process the request in received MSG message.
     *
     * @param message MSG Message received.
     *
     * @see MessageMSG
     */
    public void receiveMSG(MessageMSG message);
}

Index: Channel.java
===================================================================
RCS file: /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/core/Channel.java,v
retrieving revision 1.32
retrieving revision 1.33
diff -C2 -r1.32 -r1.33
*** Channel.java	21 Apr 2003 15:09:10 -0000	1.32
--- Channel.java	10 Jun 2003 18:59:16 -0000	1.33
***************
*** 60,63 ****
--- 60,64 ----
       * @param listener
       * @return The previous MessageListener or null if none was set.
+      * @deprecated
       */
      public MessageListener setMessageListener(MessageListener listener);
***************
*** 65,72 ****
--- 66,103 ----
      /**
       * Returns the message listener for this channel.
+      * @deprecated
       */
      public MessageListener getMessageListener();
  
      /**
+      * Returns the <code>RequestHandler</code> registered with this channel.
+      */
+     public RequestHandler getRequestHandler();
+     
+     /**
+      * Sets the MSG handler for this <code>Channel</code>.
+      * 
+      * @param handler <code>RequestHandler</code> to handle received
+      *                MSG messages.
+      * @return The previous <code>RequestHandler</code> or <code>null</code> if
+      *         one wasn't set.
+      */
+     public RequestHandler setRequestHandler(RequestHandler handler);
+     
+     /**
+      * Sets the MSG handler for this <code>Channel</code>.
+      * 
+      * @param handler <code>RequestHandler</code> to handle received
+      *                MSG messages.
+      * @param tuningReset flag indicating that the profile will request a
+      *                    tuning reset.
+      * 
+      * @return The previous <code>RequestHandler</code> or <code>null</code> if
+      *         one wasn't set.
+      */
+     public RequestHandler setRequestHandler(RequestHandler handler,
+                                             boolean tuningReset);
+ 
+     /**
       * Returns the session for this channel.
       *
***************
*** 92,97 ****
--- 123,134 ----
              throws BEEPException;
  
+     /**
+      * @deprecated
+      */
      public void setStartData(String data);
  
+     /**
+      * @deprecated
+      */
      public String getStartData();
  

Index: ChannelImpl.java
===================================================================
RCS file: /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/core/ChannelImpl.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -r1.6 -r1.7
*** ChannelImpl.java	3 Jun 2003 16:38:35 -0000	1.6
--- ChannelImpl.java	10 Jun 2003 18:59:17 -0000	1.7
***************
*** 21,24 ****
--- 21,26 ----
  import java.util.*;
  
+ import edu.oswego.cs.dl.util.concurrent.PooledExecutor;
+ 
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
***************
*** 38,42 ****
   *
   */
! class ChannelImpl implements Channel {
  
      // class variables
--- 40,44 ----
   *
   */
! class ChannelImpl implements Channel, Runnable {
  
      // class variables
***************
*** 54,57 ****
--- 56,62 ----
          new BufferSegment(new byte[0]);
  
+     private static final PooledExecutor callbackQueue =
+         new PooledExecutor();
+ 
      /** @todo check this */
  
***************
*** 59,62 ****
--- 64,69 ----
      static final int DEFAULT_WINDOW_SIZE = 4096;
  
+     static final RequestHandler defaultHandler = new DefaultMSGHandler();
+ 
      // instance variables
  
***************
*** 75,80 ****
      private String startData;
  
!     /** receiver of messages (or partial messages) */
!     private MessageListener listener;
  
      /** number of last message sent */
--- 82,87 ----
      private String startData;
  
!     /** receiver of MSG messages */
!     private RequestHandler handler;
  
      /** number of last message sent */
***************
*** 117,153 ****
      private int recvWindowFreed;
  
-     private boolean notifyOnFirstFrame = true;
- 
      private Object applicationData = null;
  
-     private boolean blockingMessageListener = false;
- 
      // tuningProfile indicates that the profile for this channel will
      // request a tuning reset
      private boolean tuningProfile = false;
  
!     // in shutting down the session
!     // something for waiting synchronous messages (semaphores or something)
! 
!     /**
!      * Create a <code>Channel</code> object.
!      *
!      * @param profile URI string of the profile that this channel will "speak".
!      * @param number The channel number.
!      * @param listener message listener that will receive callbacks for
!      *    messages received on this channel
!      * @param session <code>Session</code> over which this channel
!      *                sends/receives messages
!      *
!      * @see org.beepcore.beep.core.Session
!      * @see org.beepcore.beep.core.MessageListener
!      */
!     protected ChannelImpl(String profile, String number, MessageListener listener,
!                       boolean blocking, SessionImpl session)
      {
          this.profile = profile;
          this.encoding = Constants.ENCODING_DEFAULT;
          this.number = number;
!         this.setMessageListener(listener, blocking);
          this.session = session;
          sentSequence = 0;
--- 124,140 ----
      private int recvWindowFreed;
  
      private Object applicationData = null;
  
      // tuningProfile indicates that the profile for this channel will
      // request a tuning reset
      private boolean tuningProfile = false;
  
!     ChannelImpl(String profile, String number,
!                 RequestHandler handler, boolean tuningReset, SessionImpl session)
      {
          this.profile = profile;
          this.encoding = Constants.ENCODING_DEFAULT;
          this.number = number;
!         this.setRequestHandler(handler, tuningReset);
          this.session = session;
          sentSequence = 0;
***************
*** 166,192 ****
      }
  
!     protected ChannelImpl(String profile, String number, SessionImpl session)
      {
!         this(profile, number, null, false, session);
      }
  
!     /**
!      * This is a special constructor for Channel Zero
!      *
!      * @param Session
!      * @param ReplyListener
!      *
!      */
!     ChannelImpl(SessionImpl session, String number, ReplyListener rl)
      {
!         this(null, number, null, false, session);
  
          // Add a MSG to the SentMSGQueue to fake channel into accepting the
          // greeting which comes in an unsolicited RPY.
!         sentMSGQueue.add(new MessageStatus(this, Message.MESSAGE_TYPE_MSG, 0,
!                                            null, rl));
!         recvMSGQueue.add(new MessageMSGImpl(this, 0, null));
  
!         state = STATE_ACTIVE;
      }
  
--- 153,178 ----
      }
  
!     ChannelImpl(String profile, String number, SessionImpl session)
      {
!         this(profile, number, defaultHandler, false, session);
      }
  
!     static ChannelImpl createChannelZero(SessionImpl session,
!                                          ReplyListener reply,
!                                          RequestHandler handler)
      {
!         ChannelImpl channel = new ChannelImpl(null, "0", handler,
!                                               true, session);
  
          // Add a MSG to the SentMSGQueue to fake channel into accepting the
          // greeting which comes in an unsolicited RPY.
!         channel.sentMSGQueue.add(new MessageStatus(channel,
!                                                    Message.MESSAGE_TYPE_MSG, 0,
!                                                    null, reply));
!         channel.recvMSGQueue.add(new MessageMSGImpl(channel, 0, null));
! 
!         channel.state = STATE_ACTIVE;
  
!         return channel;
      }
  
***************
*** 301,325 ****
      public MessageListener setMessageListener(MessageListener ml)
      {
-         return setMessageListener(ml, true);
-     }
-     
-     MessageListener setMessageListener(MessageListener ml,
-                                        boolean blocking)
-     {
          MessageListener tmp = getMessageListener();
  
!         if (ml == null) {
!             this.listener = null;
!             this.blockingMessageListener = false;
!             return tmp;
!         }
!         
!         if (blocking) {
!             this.listener = new ThreadedMessageListener(this, ml);
!         } else {
!             this.listener = ml;
!         }
  
-         this.blockingMessageListener = blocking;
          return tmp;
      }
--- 287,294 ----
      public MessageListener setMessageListener(MessageListener ml)
      {
          MessageListener tmp = getMessageListener();
  
!         this.handler = new MessageListenerAdapter(ml);
  
          return tmp;
      }
***************
*** 330,339 ****
      public MessageListener getMessageListener()
      {
!         if (this.blockingMessageListener) {
!             return
!                 ((ThreadedMessageListener)this.listener).getMessageListener();
!         } else {
!             return this.listener;
          }
      }
  
--- 299,346 ----
      public MessageListener getMessageListener()
      {
!         if (!(this.handler instanceof MessageListenerAdapter)) {
!             return null;
          }
+         
+         return ((MessageListenerAdapter)this.handler).getMessageListener();
+     }
+ 
+     /**
+      * Returns the <code>RequestHandler</code> registered with this channel.
+      */
+     public RequestHandler getRequestHandler()
+     {
+         return this.handler;
+     }
+     
+     /**
+      * Sets the MSG handler for this <code>Channel</code>.
+      * 
+      * @param handler <code>RequestHandler</code> to handle received MSG messages.
+      * @return The previous <code>RequestHandler</code> or <code>null</code> if
+      *         one wasn't set.
+      */
+     public RequestHandler setRequestHandler(RequestHandler handler)
+     {
+         return this.setRequestHandler(handler, false);
+     }
+ 
+     /**
+      * Sets the MSG handler for this <code>Channel</code>.
+      * 
+      * @param handler <code>RequestHandler</code> to handle received MSG messages.
+      * @param tuningReset flag indicating that the profile will request a
+      *                    tuning reset.
+      * @return The previous <code>RequestHandler</code> or <code>null</code> if
+      *         one wasn't set.
+      */
+     public RequestHandler setRequestHandler(RequestHandler handler, boolean tuningReset)
+     {
+         RequestHandler tmp = this.handler;
+         
+         this.handler = handler;
+         this.tuningProfile = tuningReset;
+         
+         return tmp;
      }
  
***************
*** 347,350 ****
--- 354,369 ----
      }
  
+     public void run() {
+         MessageMSGImpl m;
+         synchronized (recvMSGQueue) {
+                 m = (MessageMSGImpl) recvMSGQueue.getFirst();
+                 synchronized (m) {
+                     m.setNotified();
+                 }
+         }
+ 
+         handler.receiveMSG(m);
+     }
+ 
      /**
       * Sends a message of type MSG.
***************
*** 470,487 ****
                  if (recvMSGQueue.size() == 1) {
                      try {
!                         listener.receiveMSG(m);
!                     } catch (BEEPError e) {
!                         try {
!                             m.sendERR(e);
!                         } catch (BEEPException e2) {
!                             log.error("Error sending ERR", e2);
!                         }
!                     } catch (AbortChannelException e) {
!                         try {
!                             /* @todo change this to abort or something else */
!                             ChannelImpl.this.close();
!                         } catch (BEEPException e2) {
!                             log.error("Error closing channel", e2);
!                         }
                      }
                  }
--- 489,496 ----
                  if (recvMSGQueue.size() == 1) {
                      try {
!                         callbackQueue.execute(this);
!                     } catch (InterruptedException e) {
!                         /** @TODO handle this better */
!                         throw new BEEPException(e);
                      }
                  }
***************
*** 628,634 ****
          }
  
!         // notify message listener if this message has not been
!         // notified before and notifyOnFirstFrame is set, the
!         // window is full, this is the last frame.
          synchronized (m) {
              if (m.isNotified()) {
--- 637,641 ----
          }
  
!         // notify message listener if this message has not been notified before
          synchronized (m) {
              if (m.isNotified()) {
***************
*** 682,687 ****
          receiveFrame(frame);
  
!         return !(frame.isLast() == true &&
!                  getState() == STATE_TUNING || tuningProfile == true);
      }
  
--- 689,697 ----
          receiveFrame(frame);
  
!         if (frame.getMessageType() == Message.MESSAGE_TYPE_MSG) {
!             return !(frame.isLast() == true && tuningProfile == true);
!         } else {
!             return !(frame.isLast() == true && getState() == STATE_TUNING);
!         }
      }
  
***************
*** 830,847 ****
              if (m != null) {
                  try {
!                     listener.receiveMSG(m);
!                 } catch (BEEPError e) {
!                     try {
!                         m.sendERR(e);
!                     } catch (BEEPException e2) {
!                         log.error("Error sending ERR", e2);
!                     }
!                 } catch (AbortChannelException e) {
!                     try {
!                         /* @todo change this to abort or something else */
!                         ChannelImpl.this.close();
!                     } catch (BEEPException e2) {
!                         log.error("Error closing channel", e2);
!                     }
                  }
              }
--- 840,847 ----
              if (m != null) {
                  try {
!                     callbackQueue.execute(this);
!                 } catch (InterruptedException e) {
!                     /** @TODO handle this better */
!                     throw new BEEPException(e);
                  }
              }
***************
*** 1081,1084 ****
--- 1081,1132 ----
      {
          return startData;
+     }
+     
+     static class MessageListenerAdapter implements RequestHandler {
+         MessageListenerAdapter(MessageListener listener) {
+             this.listener = listener;
+         }
+ 
+         public void receiveMSG(MessageMSG message) {
+             try {
+                 listener.receiveMSG(message);
+             } catch (BEEPError e) {
+                 try {
+                     message.sendERR(e);
+                 } catch (BEEPException e2) {
+                     log.error("Error sending ERR", e2);
+                 }
+             } catch (AbortChannelException e) {
+                 try {
+                     message.getChannel().close();
+                 } catch (BEEPException e2) {
+                     log.error("Error closing channel", e2);
+                 }
+             }
+         }
+ 
+         public MessageListener getMessageListener() {
+             return this.listener;
+         }
+         
+         private Log log = LogFactory.getLog(this.getClass());
+         private MessageListener listener;
+     }
+ 
+     private static class DefaultMSGHandler implements RequestHandler {
+         public void receiveMSG(MessageMSG message) {
+             log.error("No handler registered to process MSG received on " +
+                       "channel " + message.getChannel().getNumber());
+             try {
+                 message.sendERR(BEEPError.CODE_REQUESTED_ACTION_ABORTED,
+                                 "No MSG handler registered");
+             } catch (BEEPException e) {
+                 log.error("Error sending ERR", e);
+             }
+         }
+ 
+         
+         private Log log = LogFactory.getLog(this.getClass());
+         private MessageListener listener;
      }
  }

Index: Session.java
===================================================================
RCS file: /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/core/Session.java,v
retrieving revision 1.35
retrieving revision 1.36
diff -C2 -r1.35 -r1.36
*** Session.java	23 Apr 2003 15:23:04 -0000	1.35
--- Session.java	10 Jun 2003 18:59:18 -0000	1.36
***************
*** 163,166 ****
--- 163,167 ----
       *                        state to create a new Channel).
       * @see MessageListener
+      * @deprecated
       */
      public Channel startChannel(String profile, MessageListener listener)
***************
*** 170,173 ****
--- 171,194 ----
       * Sends a request to start a new Channel on this Session for the
       * specified profile. This version of <code>startChannel</code> allows a
+      * <code>RequestHandler</code> to be specified to be registered once the
+      * Channel is started. This is useful for profiles that are peer-to-peer in
+      * nature.
+      *
+      * @param profile The URI of the profile for the new Channel.
+      * @param handler A <code>RequestHandler</code> to receive MSG messages
+      *                sent by the remote peer of this Session.
+      *
+      * @throws BEEPError Thrown if the remote peer is unable or refuses to
+      *                   start a new Channel for the requested profile.
+      * @throws BEEPException Thrown for errors other than those defined by
+      *                       the BEEP protocol (e.g. the Session is not in a
+      *                       state to create a new Channel).
+      */
+     public Channel startChannel(String profile, RequestHandler handler)
+             throws BEEPException, BEEPError;
+ 
+     /**
+      * Sends a request to start a new Channel on this Session for the
+      * specified profile. This version of <code>startChannel</code> allows a
       * <code>MessageListener</code> to be specified to be registered once the
       * Channel is started. This is useful for profiles that are peer-to-peer in
***************
*** 218,221 ****
--- 239,243 ----
       *                        state to create a new Channel).
       * @see MessageListener
+      * @deprecated
       */
      public Channel startChannel(String profile, boolean base64Encoding,
***************
*** 224,227 ****
--- 246,268 ----
  
      /**
+      * Sends a request to start a new Channel on this Session for the
+      * specified profile. This version of <code>startChannel</code> allows a
+      * <code>RequestHandler</code> to be specified to be registered once the
+      * Channel is started.
+      *
+      * @param profile
+      * @param handler A <code>RequestHandler</code> to receive MSG messages
+      *                sent by the remote peer of this Session.
+      *
+      * @throws BEEPError Thrown if the remote peer is unable or refuses to
+      *                   start a new Channel for the requested profile.
+      * @throws BEEPException Thrown for errors other than those defined by
+      *                       the BEEP protocol (e.g. the Session is not in a
+      *                       state to create a new Channel).
+      */
+     public Channel startChannel(StartChannelProfile profile, RequestHandler handler)
+             throws BEEPException, BEEPError;
+ 
+     /**
       * Sends a start channel request using the given list of profiles.
       *
***************
*** 237,244 ****
--- 278,303 ----
       * @see StartChannelProfile
       * @see MessageListener
+      * @deprecated
       */
      public Channel startChannel(Collection profiles, MessageListener listener)
          throws BEEPException, BEEPError;
  
+     /**
+      * Sends a start channel request using the given list of profiles.
+      *
+      * @param profiles A collection of <code>StartChannelProfile</code>(s).
+      * @param handler A <code>RequestHandler</code> to receive MSG messages
+      *                sent by the remote peer of this Session.
+      *
+      * @throws BEEPError Thrown if the remote peer is unable or refuses to
+      *                   start a new Channel for the requested profile.
+      * @throws BEEPException Thrown for errors other than those defined by
+      *                       the BEEP protocol (e.g. the Session is not in a
+      *                       state to create a new Channel).
+      * @see StartChannelProfile
+      * @see RequestHandler
+      */
+     public Channel startChannel(Collection profiles, RequestHandler handler)
+         throws BEEPException, BEEPError;
  
      /**

Index: SessionImpl.java
===================================================================
RCS file: /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/core/SessionImpl.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -C2 -r1.7 -r1.8
*** SessionImpl.java	3 Jun 2003 16:38:35 -0000	1.7
--- SessionImpl.java	10 Jun 2003 18:59:19 -0000	1.8
***************
*** 173,178 ****
          GreetingListener greetingListener = new GreetingListener();
  
!         zero = new ChannelImpl(this, CHANNEL_ZERO, greetingListener);
!         zero.setMessageListener(new ChannelZeroListener(), false);
  
          channels.put(CHANNEL_ZERO, zero);
--- 173,178 ----
          GreetingListener greetingListener = new GreetingListener();
  
!         zero = ChannelImpl.createChannelZero(this, greetingListener,
!                                              new ChannelImpl.MessageListenerAdapter(new ChannelZeroListener()));
  
          channels.put(CHANNEL_ZERO, zero);
***************
*** 224,229 ****
          GreetingListener greetingListener = new GreetingListener();
  
!         zero = new ChannelImpl(this, CHANNEL_ZERO, greetingListener);
!         zero.setMessageListener(new ChannelZeroListener(), false);
          channels.put(CHANNEL_ZERO, zero);
  
--- 224,229 ----
          GreetingListener greetingListener = new GreetingListener();
  
!         zero = ChannelImpl.createChannelZero(this, greetingListener,
!                                              new ChannelImpl.MessageListenerAdapter(new ChannelZeroListener()));
          channels.put(CHANNEL_ZERO, zero);
  
***************
*** 420,455 ****
      }
  
-     /**
-      * Sends a start channel request using the specified profile.
-      *
-      * @param profile The uri of the profile for the channel you wish to start.
-      *
-      * @return A <code>Channel</code> for the specified profile.
-      *
-      * @throws BEEPError Thrown if an error occurs in the under lying transport.
-      * @throws BEEPException Thrown if any of the parameters are invalid,
-      * or if the profile is unavailable on this <code>Session</code>.
-      */
      public Channel startChannel(String profile)
              throws BEEPException, BEEPError
      {
!         return startChannel(profile, null);
      }
  
-     /**
-      * Sends a start channel request using the specified profile.
-      *
-      * @param profile The uri of the profile for the channel you wish to start.
-      * @param listener An implementation of <code>MessageListener</code> that
-      * is to receive message callbacks for this channel.  It can be null, but
-      * don't expect to be called back.
-      *
-      * @return A <code>Channel</code> for the specified profile.
-      *
-      * @throws BEEPError Thrown if an error occurs in the under lying transport.
-      * @throws BEEPException Thrown if any of the parameters are invalid,
-      * or if the profile is unavailable on this <code>Session</code>.
-      * @see MessageListener
-      */
      public Channel startChannel(String profile, MessageListener listener)
              throws BEEPException, BEEPError
--- 420,429 ----
      }
  
      public Channel startChannel(String profile)
              throws BEEPException, BEEPError
      {
!         return startChannel(profile, (RequestHandler)null);
      }
  
      public Channel startChannel(String profile, MessageListener listener)
              throws BEEPException, BEEPError
***************
*** 463,493 ****
      }
  
      public Channel startChannel(String profile, boolean base64Encoding,
                                  String data)
              throws BEEPException, BEEPError
      {
!         return startChannel(profile, base64Encoding, data, null);
      }
      
-     /**
-      * Sends a start channel request using the specified profile.
-      *
-      * @param profile The uri of the profile for the channel you wish to start.
-      * @param base64Encoding Indicates whether or not the data is base64
-      * encoded.
-      * @param data The associated data or initial element for the profile of
-      * the channel you wish to start.
-      * @param listener An implementation of <code>MessageListener</code> that
-      * is to receive message callbacks for this channel.  It can be null, but
-      * don't expect to be called back.
-      *
-      * @return A <code>Channel<code> for the specified profile.
-      *
-      * @throws BEEPError Thrown if an error occurs in the under lying
-      *         transport.
-      * @throws BEEPException Thrown if any of the parameters are invalid,
-      * or if the profile is unavailable on this <code>Session</code>.
-      * @see MessageListener
-      */
      public Channel startChannel(String profile, boolean base64Encoding,
                                  String data, MessageListener listener)
--- 437,460 ----
      }
  
+     public Channel startChannel(String profile, RequestHandler handler)
+             throws BEEPException, BEEPError
+     {
+         StartChannelProfile p = new StartChannelProfile(profile);
+         LinkedList l = new LinkedList();
+ 
+         l.add(p);
+ 
+         return startChannelRequest(l, handler, false);
+     }
+ 
      public Channel startChannel(String profile, boolean base64Encoding,
                                  String data)
              throws BEEPException, BEEPError
      {
!         StartChannelProfile p = new StartChannelProfile(profile,
!                                                         base64Encoding, data);
!         return startChannel(p, null);
      }
      
      public Channel startChannel(String profile, boolean base64Encoding,
                                  String data, MessageListener listener)
***************
*** 502,523 ****
          return startChannelRequest(l, listener, false);
      }
  
-     /**
-      * Sends a start channel request using the given list of profiles.
-      *
-      * @param profiles A collection of <code>StartChannelProfile</code>(s).
-      * @param listener An implementation of <code>MessageListener</code>
-      * that is to receive message callbacks for this channel.
-      * It can be null, but don't expect to be called back.
-      *
-      * @return a started channel for the profile selected by the listener
-      *
-      * @throws BEEPError Thrown if an error occurs in the under lying
-      *         transport.
-      * @throws BEEPException Thrown if any of the parameters are invalid,
-      * or if the profile is unavailable on this <code>Session</code>.
-      * @see StartChannelProfile
-      * @see MessageListener
-      */
      public Channel startChannel(Collection profiles, MessageListener listener)
          throws BEEPException, BEEPError
--- 469,483 ----
          return startChannelRequest(l, listener, false);
      }
+     
+     public Channel startChannel(StartChannelProfile profile, RequestHandler handler)
+             throws BEEPException, BEEPError
+     {
+         LinkedList l = new LinkedList();
+ 
+         l.add(profile);
+ 
+         return startChannelRequest(l, handler, false);
+     }
  
      public Channel startChannel(Collection profiles, MessageListener listener)
          throws BEEPException, BEEPError
***************
*** 526,539 ****
      }
  
-     /**
-      * You should not see this.
-      */
      Channel startChannelRequest(Collection profiles, MessageListener listener,
                                  boolean tuning)
              throws BEEPException, BEEPError
      {
  
-         // Block here if there's an exclusive lock, which
-         // would change our channel #...
          String channelNumber = getNextFreeChannelNumber();
  
--- 486,509 ----
      }
  
      Channel startChannelRequest(Collection profiles, MessageListener listener,
                                  boolean tuning)
+         throws BEEPException, BEEPError
+     {
+         return startChannelRequest(profiles,
+                                    listener == null ? null : new ChannelImpl.MessageListenerAdapter(listener),
+                                    tuning);
+     }
+ 
+     public Channel startChannel(Collection profiles, RequestHandler handler)
+         throws BEEPException, BEEPError
+     {
+         return startChannelRequest(profiles, handler, false);
+     }
+ 
+     Channel startChannelRequest(Collection profiles, RequestHandler handler,
+                                 boolean tuning)
              throws BEEPException, BEEPError
      {
  
          String channelNumber = getNextFreeChannelNumber();
  
***************
*** 576,580 ****
          // @todo handle the data element
          // Create a channel
!         ChannelImpl ch = new ChannelImpl(null, channelNumber, listener, true, this);
  
          // Make a message
--- 546,551 ----
          // @todo handle the data element
          // Create a channel
!         ChannelImpl ch = new ChannelImpl(null, channelNumber, handler, false,
!                                          this);
  
          // Make a message
***************
*** 991,995 ****
          ch.setState(ChannelImpl.STATE_ACTIVE);
          channels.put(ch.getNumberAsString(), ch);
!         ((Message)zero.getAppData()).sendRPY(ds);
      }
  
--- 962,966 ----
          ch.setState(ChannelImpl.STATE_ACTIVE);
          channels.put(ch.getNumberAsString(), ch);
!         ((MessageMSG)zero.getAppData()).sendRPY(ds);
      }
  
***************
*** 1089,1092 ****
--- 1060,1065 ----
          }
  
+         enableIO();
+                 
          ChannelImpl channel = (ChannelImpl) channels.get(channelNumber);
  
***************
*** 1115,1119 ****
  
          try {
!             ((Message)zero.getAppData()).sendRPY(sds);
          } catch (BEEPException x) {
              terminate("Error sending RPY for <close>");
--- 1088,1092 ----
  
          try {
!             ((MessageMSG)zero.getAppData()).sendRPY(sds);
          } catch (BEEPException x) {
              terminate("Error sending RPY for <close>");
***************
*** 1167,1170 ****
--- 1140,1144 ----
                      changeState(SESSION_STATE_ACTIVE);
  
+                     enableIO();
                      throw e;
                  } catch (BEEPException x) {
***************
*** 1182,1186 ****
  
          try {
!             ((Message)zero.getAppData()).sendRPY(sds);
          } catch (BEEPException x) {
              terminate("Error sending RPY for <close> for channel 0");
--- 1156,1160 ----
  
          try {
!             ((MessageMSG)zero.getAppData()).sendRPY(sds);
          } catch (BEEPException x) {
              terminate("Error sending RPY for <close> for channel 0");
***************
*** 1189,1194 ****
          }
  
-         this.disableIO();
- 
          try {
              this.changeState(SESSION_STATE_CLOSED);
--- 1163,1166 ----
***************
*** 1240,1245 ****
       *  we've received a start channel request over the wire.
       */
!     private boolean processStartChannel(String channelNumber,
!                                         Collection profiles)
              throws BEEPError
      {
--- 1212,1217 ----
       *  we've received a start channel request over the wire.
       */
!     private void processStartChannel(String channelNumber,
!                                      Collection profiles)
              throws BEEPError
      {
***************
*** 1270,1282 ****
                  fireChannelStarted(ch);
  
!                 return true;
              } catch (StartChannelException e) {
                  try {
!                     ((Message)zero.getAppData()).sendERR(e);
                  } catch (BEEPException x) {
                      terminate("Error sending ERR response to start channel");
                  }
  
!                 return false;
              }
  
--- 1242,1254 ----
                  fireChannelStarted(ch);
  
!                 return;
              } catch (StartChannelException e) {
                  try {
!                     ((MessageMSG)zero.getAppData()).sendERR(e);
                  } catch (BEEPException x) {
                      terminate("Error sending ERR response to start channel");
                  }
  
!                 return;
              }
  
***************
*** 1286,1304 ****
                  terminate("Error sending profile. " + e.getMessage());
  
!                 return false;
              }
  
              fireChannelStarted(ch);
  
!             return true;
          }
  
          try {
!             ((Message)zero.getAppData()).sendERR(BEEPError.CODE_REQUESTED_ACTION_NOT_TAKEN2, "all requested profiles are unsupported");
          } catch (Exception x) {
              terminate("Error sending error. " + x.getMessage());
          }
- 
-         return false;
      }
  
--- 1258,1278 ----
                  terminate("Error sending profile. " + e.getMessage());
  
!                 return;
              }
  
              fireChannelStarted(ch);
  
!             if (p.data == null || ch.getState() != ChannelImpl.STATE_TUNING) {
!                 this.enableIO();
!             }
! 
!             return;
          }
  
          try {
!             ((MessageMSG)zero.getAppData()).sendERR(BEEPError.CODE_REQUESTED_ACTION_NOT_TAKEN2, "all requested profiles are unsupported");
          } catch (Exception x) {
              terminate("Error sending error. " + x.getMessage());
          }
      }
  
***************
*** 1441,1477 ****
              else if (elementName.equals("close")) {
                  log.debug("Received a channel close request");
  
!                 String channelNumber = topElement.getAttribute("number");
! 
!                 if (channelNumber == null) {
!                     throw new BEEPError(BEEPError.CODE_PARAMETER_ERROR,
!                                         "Malformed <close>: no channel number");
!                 }
  
!                 String code = topElement.getAttribute("code");
  
!                 if (code == null) {
!                     throw new BEEPError(BEEPError.CODE_PARAMETER_ERROR,
!                                         "Malformed <close>: no code attribute");
!                 }
  
!                 // this attribute is implied
!                 String xmlLang = topElement.getAttribute("xml:lang");
!                 String data = null;
!                 Node dataNode = topElement.getFirstChild();
  
!                 if (dataNode != null) {
!                     data = dataNode.getNodeValue();
  
!                     if (data.length() > MAX_PCDATA_SIZE) {
!                         throw new BEEPError(BEEPError.CODE_PARAMETER_ERROR,
!                                             "Element's PCDATA exceeds " +
!                                             "the maximum size");
                      }
                  }
  
-                 SessionImpl.this.zero.setAppData(message);
-                 SessionImpl.this.receiveCloseChannel(channelNumber, code,
-                                                  xmlLang, data);
              } else {
                  throw new BEEPError(BEEPError.CODE_PARAMETER_ERROR,
--- 1415,1456 ----
              else if (elementName.equals("close")) {
                  log.debug("Received a channel close request");
+                 
+                 try {
+                     String channelNumber = topElement.getAttribute("number");
  
!                     if (channelNumber == null) {
!                         throw new BEEPError(BEEPError.CODE_PARAMETER_ERROR,
!                                             "Malformed <close>: no channel number");
!                     }
  
!                     String code = topElement.getAttribute("code");
  
!                     if (code == null) {
!                         throw new BEEPError(BEEPError.CODE_PARAMETER_ERROR,
!                                             "Malformed <close>: no code attribute");
!                     }
  
!                     // this attribute is implied
!                     String xmlLang = topElement.getAttribute("xml:lang");
!                     String data = null;
!                     Node dataNode = topElement.getFirstChild();
  
!                     if (dataNode != null) {
!                         data = dataNode.getNodeValue();
  
!                         if (data.length() > MAX_PCDATA_SIZE) {
!                             throw new BEEPError(BEEPError.CODE_PARAMETER_ERROR,
!                                                 "Element's PCDATA exceeds " +
!                                                 "the maximum size");
!                         }
                      }
+                     SessionImpl.this.zero.setAppData(message);
+                     SessionImpl.this.receiveCloseChannel(channelNumber, code,
+                                                          xmlLang, data);
+                 } catch (BEEPError e) {
+                     enableIO();
+                     throw e;
                  }
  
              } else {
                  throw new BEEPError(BEEPError.CODE_PARAMETER_ERROR,
***************
*** 1938,1942 ****
      static class CLOSED_SessionOperations implements SessionOperations {
          public void changeState(SessionImpl s, int newState) throws BEEPException {
!             throw new BEEPException("Illegal session state transition");
          }
  
--- 1917,1922 ----
      static class CLOSED_SessionOperations implements SessionOperations {
          public void changeState(SessionImpl s, int newState) throws BEEPException {
!             throw new BEEPException("Illegal session state transition (" +
!                                     newState + ")");
          }
  

Index: TuningResetException.java
===================================================================
RCS file: /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/core/TuningResetException.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** TuningResetException.java	8 Nov 2001 05:51:34 -0000	1.2
--- TuningResetException.java	10 Jun 2003 18:59:20 -0000	1.3
***************
*** 37,40 ****
--- 37,41 ----
       * @param message
       *
+      * @TODO remove this class
       */
      public TuningResetException(String message)

--- ThreadedMessageListener.java DELETED ---



-------------------------------------------------------
This SF.net email is sponsored by:  Etnus, makers of TotalView, The best
thread debugger on the planet. Designed with thread debugging features
you've never dreamed of, try TotalView 6 free at www.etnus.com.