package org.jpos.iso.channel;
/**
 * sends back requests, posibly applying filters
 * @author <a href="mailto:apr@cs.com.uy">Alejandro P. Revilla</a>
 * @version $Revision$ $Date$
 * @since 1.2.2
 */

import java.io.IOException;
import org.jpos.iso.ISOMsg;
import org.jpos.iso.ISOChannel;
import org.jpos.iso.ISOPackager;
import org.jpos.iso.ISOException;
import org.jpos.util.NameRegistrar;
import org.jpos.util.BlockingQueue;
import org.jpos.util.Logger;
import org.jpos.util.LogEvent;
import org.jpos.util.LogSource;
import org.jpos.iso.ISOFilter.VetoException;

public class LoopbackChannel implements ISOChannel, LogSource {
    boolean usable = true;
    private int[] cnt;
    String name;
    BlockingQueue queue;
    Logger logger;
    String realm;

    public LoopbackChannel () {
	super();
        cnt = new int[SIZEOF_CNT];
	queue = new BlockingQueue();
    }

    public void setPackager(ISOPackager p) {
	// do nothing - N/A
    }

    public void connect () {
	cnt[CONNECT]++;
	usable = true;
    }

    /**
     * disconnects ISOChannel
     * @exception IOException
     */
    public void disconnect () {
	usable = false;
    }

    public void reconnect() {
	usable = true;
    }

    public boolean isConnected() {
	return usable;
    }

    public void send (ISOMsg m)
	throws IOException,ISOException, VetoException
    {
	cnt[TX]++;
	Logger.log (new LogEvent (this, "loopback-send", m));
	queue.enqueue (m);
    }

    public ISOMsg receive() throws IOException, ISOException
    {
	try {
	    ISOMsg m = (ISOMsg) queue.dequeue();
	    cnt[RX]++;
	    Logger.log (new LogEvent (this, "loopback-receive", m));
	    return m;
	} catch (InterruptedException e) {
	    throw new IOException (e.toString());
	} catch (BlockingQueue.Closed e) {
	    throw new IOException (e.toString());
	}
    }

    public void setUsable(boolean b) {
	this.usable = usable;
    }

    public int[] getCounters() {
	return cnt;
    }

    public void setName (String name) {
	this.name = name;
	NameRegistrar.register ("channel."+name, this);
    }

    public String getName() {
	return name;
    }

    public ISOPackager getPackager() {
	return null;
    }

    public void resetCounters() {
        for (int i=0; i<SIZEOF_CNT; i++)
            cnt[i] = 0;
    }
    public void setLogger (Logger logger, String realm) {
	this.logger = logger;
	this.realm  = realm;
    }
    public String getRealm () {
	return realm;
    }
    public Logger getLogger() {
	return logger;
    }
}

@@ -341,32 +341,66 @@
 o.ISOException;%0A
+import org.jpos.iso.FilteredBase;%0A
 import org.jpos.
@@ -626,30 +626,39 @@
 nel 
-implements ISOChannel,
+extends FilteredBase implements
  Log
@@ -902,32 +902,151 @@
 Queue();%0A    %7D%0A%0A
+   /**%0A    * setPackager is optional on LoopbackChannel, it is%0A    * used for debugging/formating purposes only%0A    */%0A
     public void 
@@ -1074,28 +1074,22 @@
 er p
+ackager
 ) %7B%0A%09//
- do nothing -
  N/A
@@ -1499,292 +1499,554 @@
  %7B%0A%09
-cnt%5BTX%5D++;%0A%09Logger.log (new LogEvent (this, %22loopback-send%22, m));%0A%09queue.enqueue (m);%0A    %7D%0A%0A    public ISOMsg receive() throws IOException, ISOException%0A    %7B%0A%09try %7B%0A%09    ISOMsg m = (ISOMsg) queue.dequeue();%0A%09    cnt%5BRX%5D++;%0A%09    Logger.log (new LogEvent (this, %22loopback-receive%22, m)
+if (!isConnected())%0A%09    throw new ISOException (%22unconnected ISOChannel%22);%0A%09LogEvent evt = new LogEvent (this, %22loopback-send%22);%0A%09applyOutgoingFilters (m, evt);%0A%09queue.enqueue (m);%0A%09cnt%5BTX%5D++;%0A%09Logger.log (evt);%0A    %7D%0A%0A    public ISOMsg receive() throws IOException, ISOException%0A    %7B%0A%09if (!isConnected())%0A%09    throw new ISOException (%22unconnected ISOChannel%22);%0A%09try %7B%0A%09    LogEvent evt = new LogEvent (this, %22loopback-receive%22);%0A%09    ISOMsg m = (ISOMsg) queue.dequeue();%0A%09    applyIncomingFilters (m, evt);%0A%09    cnt%5BRX%5D++;%0A%09    Logger.log (evt
 );%0A%09

implement FilteredChannel