001/* 002 * jPOS Project [http://jpos.org] 003 * Copyright (C) 2000-2026 jPOS Software SRL 004 * 005 * This program is free software: you can redistribute it and/or modify 006 * it under the terms of the GNU Affero General Public License as 007 * published by the Free Software Foundation, either version 3 of the 008 * License, or (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU Affero General Public License for more details. 014 * 015 * You should have received a copy of the GNU Affero General Public License 016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 017 */ 018 019package org.jpos.iso.channel; 020 021import org.jpos.core.Configurable; 022import org.jpos.core.Configuration; 023import org.jpos.core.ConfigurationException; 024import org.jpos.iso.ISOChannel; 025import org.jpos.iso.ISOException; 026import org.jpos.iso.ISOMsg; 027import org.jpos.iso.ISOPackager; 028import org.jpos.util.LogEvent; 029import org.jpos.util.LogSource; 030import org.jpos.util.Logger; 031import org.jpos.util.NameRegistrar; 032 033import java.io.IOException; 034import java.util.List; 035import java.util.Vector; 036import java.util.concurrent.locks.Lock; 037import java.util.concurrent.locks.ReentrantLock; 038 039@SuppressWarnings("unchecked") 040public class ChannelPool implements ISOChannel, LogSource, Configurable, Cloneable { 041 boolean usable = true; 042 String name = ""; 043 protected Logger logger; 044 protected String realm; 045 Configuration cfg = null; 046 List pool; 047 ISOChannel current; 048 Lock lock = new ReentrantLock(); 049 050 public ChannelPool () { 051 super (); 052 pool = new Vector (); 053 } 054 public void setPackager(ISOPackager p) { 055 // nothing to do 056 } 057 public void connect () throws IOException { 058 lock.lock(); 059 try { 060 current = null; 061 LogEvent evt = new LogEvent (this, "connect"); 062 evt.addMessage ("pool-size=" + Integer.toString (pool.size())); 063 for (int i=0; i<pool.size(); i++) { 064 try { 065 evt.addMessage ("pool-" + Integer.toString (i)); 066 ISOChannel c = (ISOChannel) pool.get (i); 067 c.connect (); 068 if (c.isConnected()) { 069 current = c; 070 usable = true; 071 break; 072 } 073 } catch (IOException e) { 074 evt.addMessage (e); 075 } 076 } 077 if (current == null) 078 evt.addMessage ("connect failed"); 079 Logger.log (evt); 080 if (current == null) { 081 throw new IOException ("unable to connect"); 082 } 083 } finally { 084 lock.unlock(); 085 } 086 } 087 public void disconnect () throws IOException { 088 lock.lock(); 089 try { 090 current = null; 091 LogEvent evt = new LogEvent (this, "disconnect"); 092 for (Object aPool : pool) { 093 try { 094 ISOChannel c = (ISOChannel) aPool; 095 c.disconnect(); 096 } catch (IOException e) { 097 evt.addMessage(e); 098 } 099 } 100 Logger.log (evt); 101 } finally { 102 lock.unlock(); 103 } 104 105 } 106 public void reconnect() throws IOException { 107 lock.lock(); 108 try { 109 disconnect (); 110 connect (); 111 } finally { 112 lock.unlock();; 113 } 114 } 115 public boolean isConnected() { 116 lock.lock(); 117 try { 118 return getCurrent().isConnected (); 119 } catch (IOException e) { 120 return false; 121 } finally { 122 lock.unlock(); 123 } 124 } 125 public ISOMsg receive() throws IOException, ISOException { 126 return getCurrent().receive (); 127 } 128 public void send (ISOMsg m) throws IOException, ISOException { 129 getCurrent().send (m); 130 } 131 public void send (byte[] b) throws IOException, ISOException { 132 getCurrent().send (b); 133 } 134 public void setUsable(boolean b) { 135 this.usable = b; 136 } 137 public void setName (String name) { 138 this.name = name; 139 NameRegistrar.register ("channel."+name, this); 140 } 141 public String getName() { 142 return this.name; 143 } 144 public ISOPackager getPackager () { 145 return null; 146 } 147 public void setLogger (Logger logger, String realm) { 148 this.logger = logger; 149 this.realm = realm; 150 } 151 public String getRealm () { 152 return realm; 153 } 154 public Logger getLogger() { 155 return logger; 156 } 157 public void setConfiguration (Configuration cfg) 158 throws ConfigurationException 159 { 160 this.cfg = cfg; 161 String channelName[] = cfg.getAll ("channel"); 162 for (String aChannelName : channelName) { 163 try { 164 addChannel(aChannelName); 165 } catch (NameRegistrar.NotFoundException e) { 166 throw new ConfigurationException(e); 167 } 168 } 169 } 170 public void addChannel (ISOChannel channel) { 171 pool.add (channel); 172 } 173 public void addChannel (String name) 174 throws NameRegistrar.NotFoundException 175 { 176 pool.add (NameRegistrar.get ("channel."+name)); 177 } 178 public void removeChannel (ISOChannel channel) { 179 pool.remove (channel); 180 } 181 public void removeChannel (String name) throws NameRegistrar.NotFoundException { 182 pool.remove (NameRegistrar.get ("channel."+name)); 183 } 184 public int size() { 185 return pool.size(); 186 } 187 public ISOChannel getCurrent () throws IOException { 188 lock.lock(); 189 try { 190 if (current == null) 191 connect(); 192 else if (!usable) 193 reconnect(); 194 } finally { 195 lock.unlock(); 196 } 197 return current; 198 } 199 200 public Object clone(){ 201 try { 202 return super.clone(); 203 } catch (CloneNotSupportedException e) { 204 throw new InternalError(); 205 } 206 } 207} 208