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.nio.NetAgent;
009    import gov.lbl.dsd.sea.nio.util.NioUtil;
010    
011    import java.io.IOException;
012    import java.nio.ByteBuffer;
013    import java.nio.channels.SelectionKey;
014    
015    /**
016     * Response from an agent to a prior {@link ChannelRequest.Register}or
017     * {@link ChannelRequest.Close} or {@link ChannelRequest.WriteData}request;
018     * Contains the agent this response originates from, as well as the selection key
019     * of the channel the request/response are associated with (retrievable via
020     * <code>key.channel()</code>), as well as an optional exception that may
021     * have been thrown by the agent in attempting to handle the associated prior
022     * request.
023     * 
024     * @author whoschek@lbl.gov
025     * @author $Author: hoschek3 $
026     * @version $Revision: 1.13 $, $Date: 2004/07/28 19:49:20 $
027     */
028    public abstract class ChannelResponse {
029    
030            protected NetAgent agent;
031            protected SelectionKey key;
032            protected IOException exception;
033            
034            protected ChannelResponse(NetAgent agent, SelectionKey key,
035                            IOException exception) {
036                    this.agent = agent;
037                    this.key = key;
038                    this.exception = exception;
039            }
040    
041            public NetAgent getAgent() {
042                    return this.agent;
043            }
044    
045            public SelectionKey getKey() {
046                    return this.key;
047            }
048    
049            public IOException getException() {
050                    return this.exception;
051            }
052    
053            public String toString() {
054                return this.getClass().getName() +
055                ": agent=" + this.getAgent() +
056                ", key=" + this.getKey() +
057                ", exception=" + this.getException();
058            }
059            
060            /**
061             * Indicates response is to a prior {@link ChannelRequest.Register}request;
062             * The interest ops supplied to the original request can be retrieved from
063             * the response via <code>response.getInterestOps()</code>. (This is
064             * necessary because <code>key.interestOps()</code> may block on a lock held
065             * by the NIO Selector.select() operation, potentially leading to ugly race
066             * deadlocks).
067             */
068            public static class Registered extends ChannelResponse {
069                    
070                    protected int interestOps;
071                    
072                    public Registered(NetAgent agent, SelectionKey key, IOException exception, int interestOps) {
073                            super(agent, key, exception);
074                            this.interestOps = interestOps;
075                    }
076                    
077                    public int getInterestOps() {
078                            return this.interestOps;
079                    }
080                    
081                    public String toString() {
082                            return super.toString() + ", interestOps=" + NioUtil.toString(this.getInterestOps());
083                    }
084            }
085    
086            /**
087             * Indicates that an agent has accepted a new channel from a network client
088             * (originally initiated by a {@link ChannelRequest.Register}request containing
089             * {@link java.nio.channels.SelectionKey} OP_ACCEPT ops).
090             */
091            public static class Accepted extends ChannelResponse {
092    
093                    public Accepted(NetAgent agent, SelectionKey key, IOException exception) {
094                            super(agent, key, exception);
095                    }
096            }
097    
098            /**
099             * Indicates that an agent has connected to a network server (originally
100             * initiated by a {@link ChannelRequest.Register}request containing
101             * {@link java.nio.channels.SelectionKey} OP_CONNECT ops).
102             */
103            public static class Connected extends ChannelResponse {
104    
105                    public Connected(NetAgent agent, SelectionKey key, IOException exception) {
106                            super(agent, key, exception);
107                    }
108            }
109    
110            /**
111             * Indicates that an agent has closed a channel (originally initiated by a
112             * {@link ChannelRequest.Close}request).
113             */
114            public static class Closed extends ChannelResponse {
115    
116                    public Closed(NetAgent agent, SelectionKey key, IOException exception) {
117                            super(agent, key, exception);
118                    }
119            }
120    
121            /**
122             * Contains a buffer with the non-blocking data read from the given channel
123             * (originally initiated by a prior {@link ChannelRequest.Register}request
124             * containing {@link java.nio.channels.SelectionKey}OP_READ ops); The data
125             * has <code>buffer.remaining()</code> bytes, and is contained between
126             * indexes <code>0 == buffer.position()</code> and <code>buffer.limit()</code>,
127             * as usual with NIO; A buffer with <code>!buffer.hasRemaining()</code>
128             * indicates that end-of-stream has been reached for the given channel.
129             * Once your application has completely processed the contained buffer, you 
130             * can for efficiency consider reusing it (e.g. via a buffer pool).
131             */
132            public static class Read extends ChannelResponse {
133    
134                    protected ByteBuffer buffer;
135    
136                    public Read(NetAgent agent, SelectionKey key, IOException exception,
137                                    ByteBuffer buffer) {
138                            super(agent, key, exception);
139                            this.buffer = buffer;
140                    }
141    
142                    public ByteBuffer getBuffer() {
143                            return this.buffer;
144                    }
145    
146                    public String toString() {
147                            return super.toString() + ", buffer=" + this.getBuffer();
148                    }
149            }
150    
151            /**
152             * Contains a buffer with the data fully written to the given
153             * channel (originally initiated by a prior {@link ChannelRequest.WriteData}
154             * request). Once the buffer has been fully written you
155             * can for efficiency consider reusing it (e.g. via a buffer pool). The contained
156             * buffer is IDENTICAL to the buffer originally handed to the agent via a
157             * {@link ChannelRequest.WriteData}. Caution: DO NOT modify the buffer in
158             * any way until it has been fully written! Failure to observe this rule can
159             * cause MAJOR data corruption.
160             */ 
161            public static class Write extends ChannelResponse {
162    
163                    protected ByteBuffer buffer;
164    
165                    public Write(NetAgent agent, SelectionKey key, IOException exception,
166                                    ByteBuffer buffer) {
167                            super(agent, key, exception);
168                            this.buffer = buffer;
169                    }
170    
171                    public ByteBuffer getBuffer() {
172                            return this.buffer;
173                    }
174    
175                    public String toString() {
176                            return super.toString() + ", buffer=" + this.getBuffer();
177                    }
178            }
179    }