001: /*
002: * Copyright (c) xsocket.org, 2006 - 2008. All rights reserved.
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2.1 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: *
018: * Please refer to the LGPL license at: http://www.gnu.org/copyleft/lesser.txt
019: * The latest copy of this software may be found on http://www.xsocket.org/
020: */
021: package org.xsocket.connection.spi;
022:
023: import java.io.IOException;
024: import java.net.InetAddress;
025: import java.util.Map;
026:
027: /**
028: * internal IoHandler
029: *
030: *
031: * @author grro@xsocket.org
032: */
033: abstract class ChainableIoHandler implements IIoHandler {
034:
035: private ChainableIoHandler successor = null;
036: private ChainableIoHandler previous = null;
037:
038: private IIoHandlerCallback callback = null;
039:
040: /**
041: * constructor
042: *
043: * @param successor the sucessor
044: */
045: public ChainableIoHandler(ChainableIoHandler successor) {
046: setSuccessor(successor);
047: }
048:
049: /**
050: * return the successor
051: *
052: * @return the successor
053: */
054: public final ChainableIoHandler getSuccessor() {
055: return successor;
056: }
057:
058: /**
059: * set the successor
060: *
061: * @param successor the successor
062: */
063: protected final void setSuccessor(ChainableIoHandler successor) {
064: this .successor = successor;
065: if (successor != null) {
066: successor.setPrevious(this );
067: }
068: }
069:
070: /**
071: * set the previous IoHandler
072: * @param previous the previous IoHandler
073: */
074: protected final void setPrevious(ChainableIoHandler previous) {
075: this .previous = previous;
076: }
077:
078: /**
079: * get the previous IoHandler
080: * @return the previous IoHandler
081: */
082: protected final ChainableIoHandler getPrevious() {
083: return previous;
084: }
085:
086: public boolean reset() {
087: ChainableIoHandler successor = getSuccessor();
088: if (successor != null) {
089: return successor.reset();
090: }
091:
092: return true;
093: }
094:
095: /**
096: * get the local address of the underlying connection
097: *
098: * @return the local address of the underlying connection
099: */
100: public InetAddress getLocalAddress() {
101: return getSuccessor().getLocalAddress();
102: }
103:
104: /**
105: * {@inheritDoc}
106: */
107: public int getPendingWriteDataSize() {
108: ChainableIoHandler successor = getSuccessor();
109: if (successor != null) {
110: return successor.getPendingWriteDataSize();
111: } else {
112: return 0;
113: }
114: }
115:
116: /**
117: * {@inheritDoc}
118: */
119: public boolean hasDataToSend() {
120: ChainableIoHandler successor = getSuccessor();
121: if (successor != null) {
122: return successor.hasDataToSend();
123: } else {
124: return false;
125: }
126: }
127:
128: public void suspendRead() throws IOException {
129: ChainableIoHandler successor = getSuccessor();
130: if (successor != null) {
131: successor.suspendRead();
132: }
133: }
134:
135: public void resumeRead() throws IOException {
136: ChainableIoHandler successor = getSuccessor();
137: if (successor != null) {
138: successor.resumeRead();
139: }
140: }
141:
142: public String getId() {
143: return getSuccessor().getId();
144: }
145:
146: void setPreviousCallback(IIoHandlerCallback callback) {
147: this .callback = callback;
148: }
149:
150: IIoHandlerCallback getPreviousCallback() {
151: return callback;
152: }
153:
154: /**
155: * get the local port of the underlying connection
156: *
157: * @return the local port of the underlying connection
158: */
159: public int getLocalPort() {
160: return getSuccessor().getLocalPort();
161: }
162:
163: /**
164: * get the address of the remote host of the underlying connection
165: *
166: * @return the address of the remote host of the underlying connection
167: */
168: public InetAddress getRemoteAddress() {
169: return getSuccessor().getRemoteAddress();
170: }
171:
172: /**
173: * get the port of the remote host of the underlying connection
174: *
175: * @return the port of the remote host of the underlying connection
176: */
177: public int getRemotePort() {
178: return getSuccessor().getRemotePort();
179: }
180:
181: /**
182: * check, if handler is open
183: *
184: * @return true, if the handler is open
185: */
186: public boolean isOpen() {
187: return getSuccessor().isOpen();
188: }
189:
190: /**
191: * {@inheritDoc}
192: */
193: public void setIdleTimeoutMillis(long timeout) {
194: getSuccessor().setIdleTimeoutMillis(timeout);
195: }
196:
197: /**
198: * sets the connection timout
199: *
200: * @param timeout the connection timeout
201: */
202: public void setConnectionTimeoutMillis(long timeout) {
203: getSuccessor().setConnectionTimeoutMillis(timeout);
204: }
205:
206: /**
207: * gets the connection timeout
208: *
209: * @return the connection timeout
210: */
211: public long getConnectionTimeoutMillis() {
212: return getSuccessor().getConnectionTimeoutMillis();
213: }
214:
215: /**
216: * {@inheritDoc}
217: */
218: public long getIdleTimeoutMillis() {
219: return getSuccessor().getIdleTimeoutMillis();
220: }
221:
222: /**
223: * {@inheritDoc}
224: */
225: public long getRemainingMillisToConnectionTimeout() {
226: return getSuccessor().getRemainingMillisToConnectionTimeout();
227: }
228:
229: /**
230: * {@inheritDoc}
231: */
232: public long getRemainingMillisToIdleTimeout() {
233: return getSuccessor().getRemainingMillisToIdleTimeout();
234: }
235:
236: /**
237: * {@inheritDoc}
238: */
239: public Object getOption(String name) throws IOException {
240: return getSuccessor().getOption(name);
241: }
242:
243: /**
244: * {@inheritDoc}
245: */
246: @SuppressWarnings("unchecked")
247: public Map<String, Class> getOptions() {
248: return getSuccessor().getOptions();
249: }
250:
251: /**
252: * {@inheritDoc}
253: */
254: public void setOption(String name, Object value) throws IOException {
255: getSuccessor().setOption(name, value);
256: }
257:
258: /**
259: * flush the outgoing buffers
260: *
261: * @throws IOException If some other I/O error occurs
262: */
263: public abstract void flushOutgoing() throws IOException;
264:
265: @Override
266: public String toString() {
267: StringBuilder sb = new StringBuilder(this .getClass()
268: .getSimpleName()
269: + "#" + hashCode());
270:
271: ChainableIoHandler ioHandler = this ;
272: while (ioHandler.getPrevious() != null) {
273: ioHandler = ioHandler.getPrevious();
274: }
275:
276: String forwardChain = "";
277: while (ioHandler != null) {
278: forwardChain = forwardChain
279: + ioHandler.getClass().getSimpleName() + " > ";
280: ioHandler = ioHandler.getSuccessor();
281: }
282: forwardChain = forwardChain.trim();
283: forwardChain = forwardChain.substring(0,
284: forwardChain.length() - 1);
285: sb.append(" (forward chain: " + forwardChain.trim() + ")");
286:
287: return sb.toString();
288: }
289: }
|