001    /*
002     * Copyright (c) 2003, The Regents of the University of California, through
003     * Lawrence Berkeley National Laboratory (subject to receipt of any required
004     * approvals from the U.S. Dept. of Energy). All rights reserved.
005     */
006    package gov.lbl.dsd.sea.nio.event;
007    
008    import gov.lbl.dsd.sea.Stage;
009    import gov.lbl.dsd.sea.event.GenericCallbackEvent;
010    
011    import java.nio.ByteBuffer;
012    import java.nio.channels.SelectableChannel;
013    
014    /**
015     * Requests an agent to perform some action on a given channel.
016     * 
017     * @author whoschek@lbl.gov
018     * @author $Author: hoschek3 $
019     * @version $Revision: 1.18 $, $Date: 2004/07/28 19:49:20 $
020     */
021    public abstract class ChannelRequest {
022    
023            private ChannelRequest() {} // not instantiable
024            
025            /**
026             * Requests an agent to register the given
027             * {@link java.nio.channels.SelectionKey}interest ops with the given
028             * channel; The agent will enqueue future responses to the channel onto the
029             * given observer stage; If an attachment is given the agent will attach it to the channel's key.
030             */
031            public static class Register extends GenericCallbackEvent {
032                    
033                    protected Object attachment;
034                    
035                    protected static final Object NO_ATTACHMENT = new Object(); // indicates agent should not modify current attachment
036    
037                    public Register(Stage observer, SelectableChannel channel, int interestOps) {
038                            this(observer, channel, interestOps, NO_ATTACHMENT);
039                    }
040    
041                    public Register(Stage observer, SelectableChannel channel, int interestOps, Object attachment) {
042                            super(observer, channel, new Integer(interestOps));
043                            this.attachment = attachment;
044                    }
045    
046                    public int getInterestOps() {
047                            return ((Integer) this.getInfo()).intValue();
048                    }
049    
050                    public SelectableChannel getChannel() {
051                            return (SelectableChannel) this.getMessage();
052                    }
053                    
054                    /**
055                     * Returns the attachment the agent should attach to the channel's key.
056                     * 
057                     * @throws IllegalStateException if <code>hasAttachment() == false</code>.
058                     */
059                    public Object getAttachment() {
060                            if (!hasAttachment()) throw new IllegalStateException("no attachment available");
061                            return this.attachment;
062                    }               
063    
064                    /**
065                     * Returns whether or not the request contains an attachment.
066                     */
067                    public boolean hasAttachment() {
068                            return this.attachment != NO_ATTACHMENT;
069                    }               
070            }
071                    
072            /**
073             * Requests an agent to close the given channel.
074             */
075            public static class Close extends GenericCallbackEvent {
076    
077                    public Close(SelectableChannel channel) {
078                            super(null, channel);
079                    }
080    
081                    public SelectableChannel getChannel() {
082                            return (SelectableChannel) this.getMessage();
083                    }
084            }
085    
086            /**
087             * Requests an agent to completely write ALL of the bytes in the given buffer
088             * to the given channel; As usual with NIO, the data is contained between
089             * indexes <code>buffer.position()</code> and <code>buffer.limit()</code>,
090             * and <code>buffer.remaining()</code> bytes will be written; 
091             */
092            public static class WriteData extends GenericCallbackEvent {
093    
094                    public WriteData(SelectableChannel channel, ByteBuffer buffer) {
095                            super(null, channel, buffer);
096                    }
097    
098                    public SelectableChannel getChannel() {
099                            return (SelectableChannel) this.getMessage();
100                    }
101    
102                    public ByteBuffer getBuffer() {
103                            return (ByteBuffer) this.getInfo();
104                    }
105    
106            }       
107    
108    //      /**
109    //       * Requests an agent to add the given {@link java.nio.channels.SelectionKey}
110    //       * interest ops to the ops registered with the given channel; The agent will
111    //       * enqueue future responses to the channel onto the given observer stage; If
112    //       * an attachment is given the agent will attach it to the channel's key.
113    //       */
114    //      public static class RegisterAdd extends Register {
115    //              
116    //              public RegisterAdd(Stage observer, SelectableChannel channel, int interestOps) {
117    //                      this(observer, channel, interestOps, NO_ATTACHMENT);
118    //              }
119    //
120    //              public RegisterAdd(Stage observer, SelectableChannel channel, int interestOps, Object attachment) {
121    //                      super(observer, channel, interestOps);
122    //                      this.attachment = attachment;
123    //              }
124    //
125    //      }
126    //
127    //      /**
128    //       * Requests an agent to remove the given {@link java.nio.channels.SelectionKey}
129    //       * interest ops from the ops registered with the given channel; The agent will
130    //       * enqueue future responses to the channel onto the given observer stage; If
131    //       * an attachment is given the agent will attach it to the channel's key.
132    //       */
133    //      public static class RegisterRemove extends Register {
134    //              
135    //              public RegisterRemove(Stage observer, SelectableChannel channel, int interestOps) {
136    //                      this(observer, channel, interestOps, NO_ATTACHMENT);
137    //              }
138    //
139    //              public RegisterRemove(Stage observer, SelectableChannel channel, int interestOps, Object attachment) {
140    //                      super(observer, channel, interestOps);
141    //                      this.attachment = attachment;
142    //              }
143    //
144    //      }
145    //
146    //      /**
147    //       * Requests an agent to assign the given {@link java.nio.channels.SelectionKey}
148    //       * interest ops to the ops registered with the given channel; The agent will
149    //       * enqueue future responses to the channel onto the given observer stage; If
150    //       * an attachment is given the agent will attach it to the channel's key.
151    //       */
152    //      public static class RegisterSet extends Register {
153    //              
154    //              public RegisterSet(Stage observer, SelectableChannel channel, int interestOps) {
155    //                      this(observer, channel, interestOps, NO_ATTACHMENT);
156    //              }
157    //
158    //              public RegisterSet(Stage observer, SelectableChannel channel, int interestOps, Object attachment) {
159    //                      super(observer, channel, interestOps);
160    //                      this.attachment = attachment;
161    //              }
162    //
163    //      }
164    }