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.iso.*; 022import org.jpos.iso.packager.XMLPackager; 023 024import java.io.BufferedReader; 025import java.io.EOFException; 026import java.io.IOException; 027import java.io.InputStreamReader; 028import java.net.ServerSocket; 029import java.net.Socket; 030 031/** 032 * Implements an ISOChannel able to exchange <b>jPOS generated</b> (or 033 * compliant) XML based ISO-8583 messages through a Telnet session the telnet 034 * commands are simply ignored. 035 * 036 * @author <a href="mailto:apr@cs.com.uy">Alejandro P. Revilla</a> 037 * @author <a href="mailto:marksalter@talktalk.net">Mark Salter</a> 038 * @version $Id: TelnetXMLChannel.java 2594 2008-01-22 16:41:31Z apr $ 039 * 040 * @see ISOMsg 041 * @see ISOException 042 * @see ISOChannel 043 */ 044public class TelnetXMLChannel extends BaseChannel { 045 BufferedReader reader = null; 046 047 static final String isomsgStartTag = "<" + XMLPackager.ISOMSG_TAG + ">"; 048 static final String isomsgEndTag = "</" + XMLPackager.ISOMSG_TAG + ">"; 049 050 /** 051 * Public constructor (used by Class.forName("...").newInstance()) 052 */ 053 public TelnetXMLChannel() { 054 super(); 055 } 056 057 /** 058 * Constructs client ISOChannel 059 * 060 * @param host 061 * server TCP Address 062 * @param port 063 * server port number 064 * @param p 065 * an ISOPackager 066 * @see ISOPackager 067 */ 068 public TelnetXMLChannel(String host, int port, ISOPackager p) { 069 super(host, port, p); 070 } 071 072 /** 073 * Construct server ISOChannel 074 * 075 * @param p 076 * an ISOPackager 077 * @see ISOPackager 078 * @exception IOException 079 */ 080 public TelnetXMLChannel(ISOPackager p) throws IOException { 081 super(p); 082 } 083 084 /** 085 * constructs a server ISOChannel associated with a Server Socket 086 * 087 * @param p 088 * an ISOPackager 089 * @param serverSocket 090 * where to accept a connection 091 * @exception IOException 092 * @see ISOPackager 093 */ 094 public TelnetXMLChannel(ISOPackager p, ServerSocket serverSocket) 095 throws IOException { 096 super(p, serverSocket); 097 } 098 099 /** 100 * @return a byte array with the received message 101 * @exception IOException 102 */ 103 protected byte[] streamReceive() throws IOException { 104 int sp = 0; 105 StringBuilder sb = new StringBuilder(); 106 while (reader != null) { 107 /* 108 * Throw away any telnet commands - each is 3 bytes first being 109 * x'FF'... 110 */ 111 reader.mark(3); // Mark the current position in case there are no 112 // telnet commands (FFnnmm) 113 while (reader.read() == 255) { 114 reader.skip(2); 115 reader.mark(3); 116 } 117 reader.reset(); // Return to the first byte that was *not* a telnet 118 // command (IAC). 119 120 // Now the commands are out of the way continue with the xml stream 121 // until it closes with </isomsg>. 122 String s = reader.readLine(); 123 if (s == null) 124 throw new EOFException(); 125 int isomsgStart = s.indexOf(isomsgStartTag); 126 if (isomsgStart >= 0) { 127 sp++; 128 sb.append(s, isomsgStart, s.length() - isomsgStart); 129 } else { 130 int isomsgEnd = s.indexOf(isomsgEndTag); 131 if (isomsgEnd >= 0) { 132 sb.append(s,0,isomsgEnd + isomsgEndTag.length()); 133 if (--sp <= 0) 134 break; 135 } else { 136 if (sp > 0) 137 sb.append(s); 138 } 139 } 140 141 } 142 return sb.toString().getBytes(); 143 } 144 145 protected int getHeaderLength() { 146 // XML Channel does not support header 147 return 0; 148 } 149 150 protected void sendMessageHeader(ISOMsg m, int len) { 151 // XML Channel does not support header 152 } 153 154 protected void connect(Socket socket) throws IOException { 155 super.connect(socket); 156 reader = new BufferedReader(new InputStreamReader(serverIn)); 157 } 158 159 public void disconnect() throws IOException { 160 super.disconnect(); 161 if (reader != null) 162 reader.close(); 163 reader = null; 164 } 165}