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.core.Configuration; 023import org.jpos.core.ConfigurationException; 024 025import java.io.IOException; 026import java.net.ServerSocket; 027import java.math.BigInteger; 028 029/** 030 * ISOChannel implementation suitable for OASIS Ltd © hosts<br> 031 * Message length header: n ASCII digits, configurable by setLengthDigits() (default: 4) 032 * or the 'length-digits' Configuration property. 033 * 034 * @author apr@cs.com.uy 035 * @version $Id$ 036 * @see ISOMsg 037 * @see ISOException 038 * @see ISOChannel 039 */ 040public class ASCIIChannel extends BaseChannel { 041 042 /** Number of digits for the message length header */ 043 protected int lengthDigits= 4; // 4 is default 044 045 private static final BigInteger ten= BigInteger.valueOf(10L); // just a static 10 046 047 /** 048 * Public constructor (used by Class.forName("...").newInstance()) 049 */ 050 public ASCIIChannel () { 051 super(); 052 } 053 /** 054 * Construct client ISOChannel 055 * @param host server TCP Address 056 * @param port server port number 057 * @param p an ISOPackager 058 * @see ISOPackager 059 */ 060 public ASCIIChannel (String host, int port, ISOPackager p) { 061 super(host, port, p); 062 } 063 /** 064 * Construct server ISOChannel 065 * @param p an ISOPackager 066 * @exception IOException 067 * @see ISOPackager 068 */ 069 public ASCIIChannel (ISOPackager p) throws IOException { 070 super(p); 071 } 072 /** 073 * constructs a server ISOChannel associated with a Server Socket 074 * @param p an ISOPackager 075 * @param serverSocket where to accept a connection 076 * @exception IOException 077 * @see ISOPackager 078 */ 079 public ASCIIChannel (ISOPackager p, ServerSocket serverSocket) 080 throws IOException 081 { 082 super(p, serverSocket); 083 } 084 085 086 public void setLengthDigits(int len) { lengthDigits= len; } 087 public int getLengthDigits() { return lengthDigits; } 088 089 090 /** 091 * @param len the packed Message len 092 * @exception IOException 093 */ 094 protected void sendMessageLength(int len) throws IOException { 095 int maxLen= ten.pow(lengthDigits).intValue() - 1; // 10^lengthDigits - 1 096 097 if (len > maxLen) 098 throw new IOException ("len exceeded ("+len+" > "+maxLen+")"); 099 else if (len < 0) 100 throw new IOException ("invalid negative length ("+len+")"); 101 serverOut.write(ISOUtil.zeropad(len, lengthDigits).getBytes()); 102 } 103 /** 104 * @return the Message len 105 * @exception IOException, ISOException 106 */ 107 protected int getMessageLength() throws IOException, ISOException { 108 int l = 0; 109 byte[] b = new byte[lengthDigits]; 110 while (l == 0) { 111 serverIn.readFully(b, 0, lengthDigits); 112 try { 113 if ((l=Integer.parseInt(new String(b))) == 0 && 114 isExpectKeepAlive()) { 115 116 serverOutLock.lock(); 117 try { 118 serverOut.write(b); 119 serverOut.flush(); 120 } finally { 121 serverOutLock.unlock(); 122 } 123 } 124 } catch (NumberFormatException e) { 125 throw new ISOException ("Invalid message length "+new String(b)); 126 } 127 } 128 return l; 129 } 130 131 132 /** 133 * 134 * Calls super.setConfiguration() and then reads the 'length-digits' property, 135 * defaulting to 4 136 * 137 * @param cfg Configuration 138 * @throws ConfigurationException 139 */ 140 @Override 141 public void setConfiguration (Configuration cfg) throws ConfigurationException 142 { 143 super.setConfiguration(cfg); 144 setLengthDigits(cfg.getInt("length-digits", 4)); 145 } 146} 147