All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sshtools.ssh.message.SshMessageStore Maven / Gradle / Ivy

The newest version!
/**
 * Copyright 2003-2016 SSHTOOLS Limited. All Rights Reserved.
 *
 * For product documentation visit https://www.sshtools.com/
 *
 * This file is part of J2SSH Maverick.
 *
 * J2SSH Maverick is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * J2SSH Maverick is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with J2SSH Maverick.  If not, see .
 */
package com.sshtools.ssh.message;

import java.io.EOFException;
import java.io.IOException;
import java.io.InterruptedIOException;

import com.sshtools.logging.Log;
import com.sshtools.ssh.SshException;

/**
 * 

* This class is the central storage location for channel messages; each channel * has its own message store and the message pump delivers them here where they * are stored in a lightweight linked list. *

* * @author Lee David Painter */ public class SshMessageStore implements MessageStore { public static final int NO_MESSAGES = -1; SshAbstractChannel channel; SshMessageRouter manager; boolean closed = false; SshMessage header = new SshMessage(); int size = 0; MessageObserver stickyMessageObserver; boolean verbose = Boolean.valueOf( System.getProperty("maverick.verbose", "false")).booleanValue(); public SshMessageStore(SshMessageRouter manager, SshAbstractChannel channel, MessageObserver stickyMessageObserver) { this.manager = manager; this.channel = channel; this.stickyMessageObserver = stickyMessageObserver; header.next = header.previous = header; } /** * * @param messagefilter * @param timeout * @return SshMessage * @throws IOException * @throws InterruptedIOException */ public SshMessage nextMessage(MessageObserver observer, long timeout) throws SshException, EOFException { try { SshMessage msg = manager.nextMessage(channel, observer, timeout); if (Log.isDebugEnabled()) { if (verbose) { Log.debug(this, "got managers next message"); } } if (msg != null) { synchronized (header) { if (stickyMessageObserver.wantsNotification(msg)) { return msg; } remove(msg); return msg; } } } catch (InterruptedException ex) { throw new SshException("The thread was interrupted", SshException.INTERNAL_ERROR); } throw new EOFException( "The required message could not be found in the message store"); } public boolean isClosed() { synchronized (header) { return closed; } } private void remove(SshMessage e) { if (e == header) { throw new IndexOutOfBoundsException(); } e.previous.next = e.next; e.next.previous = e.previous; size--; } public Message hasMessage(MessageObserver observer) { if (Log.isDebugEnabled()) { if (verbose) { Log.debug(this, "waiting for header lock"); } } synchronized (header) { // this would not seem to take account of header being null, or // header.next.next being null, perhaps because these states are not // possible? if so document, if not fix. SshMessage e = header.next; if (e == null) { if (Log.isDebugEnabled()) { if (verbose) { Log.debug(this, "header.next is null"); } } return null; } // cycle through the linked list until we reach the start point // (header), // checking to see if the message is of a type that the observer is // interested in. // ??don't seem to look at header though!?? for (; e != header; e = e.next) { if (observer.wantsNotification(e)) { if (Log.isDebugEnabled()) { if (verbose) { Log.debug(this, "found message"); } } return e; } } if (Log.isDebugEnabled()) { if (verbose) { Log.debug(this, "no messages"); } } return null; } } public void close() { synchronized (header) { closed = true; } } void addMessage(SshMessage msg) { synchronized (header) { // insert this message between header and header.previous, and // change their links appropriately msg.next = header; msg.previous = header.previous; // change message before header msg.previous.next = msg; // change header msg.next.previous = msg; size++; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy