001: /*
002: * SSHTools - Java SSH2 API
003: *
004: * Copyright (C) 2002-2003 Lee David Painter and Contributors.
005: *
006: * Contributions made by:
007: *
008: * Brett Smith
009: * Richard Pernavas
010: * Erwin Bolwidt
011: *
012: * This program is free software; you can redistribute it and/or
013: * modify it under the terms of the GNU General Public License
014: * as published by the Free Software Foundation; either version 2
015: * of the License, or (at your option) any later version.
016: *
017: * This program is distributed in the hope that it will be useful,
018: * but WITHOUT ANY WARRANTY; without even the implied warranty of
019: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
020: * GNU General Public License for more details.
021: *
022: * You should have received a copy of the GNU General Public License
023: * along with this program; if not, write to the Free Software
024: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
025: */
026: package com.sshtools.j2ssh.connection;
027:
028: import org.apache.commons.logging.Log;
029: import org.apache.commons.logging.LogFactory;
030:
031: import java.io.IOException;
032:
033: import java.util.Iterator;
034: import java.util.Vector;
035:
036: /**
037: *
038: *
039: * @author $author$
040: * @version $Revision: 1.12 $
041: */
042: public abstract class BindingChannel extends Channel {
043: private Log log = LogFactory.getLog(BindingChannel.class);
044:
045: /** */
046: protected BindingChannel boundChannel;
047:
048: /** */
049: protected Vector messages = new Vector();
050:
051: /**
052: *
053: *
054: * @return
055: */
056: public boolean isBound() {
057: return boundChannel != null;
058: }
059:
060: /**
061: *
062: *
063: * @param boundChannel
064: *
065: * @throws IOException
066: */
067: public void bindChannel(BindingChannel boundChannel)
068: throws IOException {
069: if (boundChannel == null) {
070: throw new IOException("[" + getName()
071: + "] Bound channel cannot be null");
072: }
073:
074: if (isBound()) {
075: throw new IOException(
076: "["
077: + getName()
078: + "] This channel is already bound to another channel ["
079: + boundChannel.getName() + "]");
080: }
081:
082: this .boundChannel = boundChannel;
083:
084: if (!boundChannel.isBound()) {
085: boundChannel.bindChannel(this );
086:
087: synchronized (messages) {
088: if (boundChannel.isOpen() && (messages.size() > 0)) {
089: sendOutstandingMessages();
090: }
091: }
092: } else {
093: if (!boundChannel.boundChannel.equals(this )) {
094: throw new IOException(
095: "["
096: + getName()
097: + "] Channel is already bound to an another channel ["
098: + boundChannel.boundChannel.getName()
099: + "]");
100: }
101: }
102: }
103:
104: private void sendOutstandingMessages() throws IOException {
105: // Send the outstanding messages
106: if (boundChannel == null) {
107: return;
108: }
109:
110: synchronized (messages) {
111: Iterator it = messages.iterator();
112:
113: while (it.hasNext()) {
114: Object obj = it.next();
115:
116: if (obj instanceof SshMsgChannelData) {
117: boundChannel
118: .sendChannelData(((SshMsgChannelData) obj)
119: .getChannelData());
120: } else if (obj instanceof SshMsgChannelExtendedData) {
121: boundChannel.sendChannelExtData(
122: ((SshMsgChannelExtendedData) obj)
123: .getDataTypeCode(),
124: ((SshMsgChannelExtendedData) obj)
125: .getChannelData());
126: } else {
127: throw new IOException(
128: "["
129: + getName()
130: + "] Invalid message type in pre bound message list!");
131: }
132: }
133:
134: messages.clear();
135: }
136: }
137:
138: /**
139: *
140: *
141: * @param msg
142: *
143: * @throws java.io.IOException
144: */
145: protected void onChannelExtData(SshMsgChannelExtendedData msg)
146: throws java.io.IOException {
147: synchronized (messages) {
148: if (boundChannel != null) {
149: if (boundChannel.isOpen()) {
150: boundChannel.sendChannelExtData(msg
151: .getDataTypeCode(), msg.getChannelData());
152: } else {
153: messages.add(msg);
154: }
155: }
156: }
157: }
158:
159: /**
160: *
161: *
162: * @param msg
163: *
164: * @throws java.io.IOException
165: */
166: protected void onChannelData(SshMsgChannelData msg)
167: throws java.io.IOException {
168: synchronized (messages) {
169: if (boundChannel != null) {
170: if (boundChannel.isOpen()) {
171: boundChannel.sendChannelData(msg.getChannelData());
172: } else {
173: messages.add(msg);
174: }
175: }
176: }
177: }
178:
179: /*public void setLocalEOF() throws IOException {
180: synchronized(state) {
181: super.setLocalEOF();
182: if (!boundChannel.isRemoteEOF()) {
183: log.info("onLocalEOF [" + getName() + "] is setting " + boundChannel.getName() + " to EOF");
184: boundChannel.setRemoteEOF();
185: //boundChannel.setLocalEOF();
186: }
187: }
188: }*/
189: protected void setRemoteEOF() throws IOException {
190: synchronized (state) {
191: super .setRemoteEOF();
192:
193: if (!boundChannel.isLocalEOF()) {
194: log.info("onRemoteEOF [" + getName() + "] is setting "
195: + boundChannel.getName() + " to EOF");
196: boundChannel.setLocalEOF();
197:
198: //boundChannel.setRemoteEOF();
199: }
200: }
201: }
202:
203: /**
204: *
205: *
206: * @throws java.io.IOException
207: */
208: protected void onChannelEOF() throws java.io.IOException {
209: }
210:
211: /**
212: *
213: *
214: * @throws java.io.IOException
215: */
216: protected void onChannelClose() throws java.io.IOException {
217: /*synchronized(state) {
218: if (boundChannel != null) {
219: if (boundChannel.isOpen())
220: boundChannel.close();
221: }
222: }*/
223: }
224:
225: /**
226: *
227: *
228: * @throws java.io.IOException
229: */
230: protected void onChannelOpen() throws java.io.IOException {
231: synchronized (messages) {
232: if (boundChannel != null) {
233: if (boundChannel.isOpen() && (messages.size() > 0)) {
234: sendOutstandingMessages();
235: }
236: }
237: }
238: }
239: }
|