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.Configuration;
022import org.jpos.core.ConfigurationException;
023import org.jpos.iso.*;
024
025import java.io.BufferedReader;
026import java.io.EOFException;
027import java.io.IOException;
028import java.io.InputStreamReader;
029import java.net.ServerSocket;
030import java.net.Socket;
031import java.util.regex.Matcher;
032import java.util.regex.Pattern;
033
034/**
035 * Extracts &lt;isomsg&gt; blocks from standard jPOS log
036 *
037 * @see ISOMsg
038 * @see ISOException
039 * @see ISOChannel
040 */
041public class LogChannel extends BaseChannel {
042    BufferedReader reader = null;
043    int timestampField=0;
044    int realmField=0;
045    private static Pattern logPattern = Pattern.compile("<log realm=\"(\\.|[^\"]*)\"\\sat=\"((\\.|[^\"])*)\"");
046    /**
047     * Public constructor (used by Class.forName("...").newInstance())
048     */
049    public LogChannel () {
050        super();
051    }
052    /**
053     * Constructs client ISOChannel
054     * @param host  server TCP Address
055     * @param port  server port number
056     * @param p     an ISOPackager
057     * @see ISOPackager
058     */
059    public LogChannel (String host, int port, ISOPackager p) {
060        super(host, port, p);
061    }
062    /**
063     * Construct server ISOChannel
064     * @param p     an ISOPackager
065     * @see ISOPackager
066     * @exception IOException
067     */
068    public LogChannel (ISOPackager p) throws IOException {
069        super(p);
070    }
071    /**
072     * constructs a server ISOChannel associated with a Server Socket
073     * @param p     an ISOPackager
074     * @param serverSocket where to accept a connection
075     * @exception IOException
076     * @see ISOPackager
077     */
078    public LogChannel (ISOPackager p, ServerSocket serverSocket) 
079        throws IOException
080    {
081        super(p, serverSocket);
082    }
083    /**
084     * @return a byte array with the received message
085     * @exception IOException
086     */
087    protected byte[] streamReceive() throws IOException {
088        StringBuilder sb = new StringBuilder();
089        String realm = null;
090        String at= null;
091        int inMsg = 0;
092        while (reader != null) {
093            String s = reader.readLine();
094            if (s == null)
095                throw new EOFException();
096            if ((timestampField > 0 || realmField > 0) && s.contains("<log") && s.contains("at=")) {
097                Matcher matcher = logPattern.matcher(s);
098                if (matcher.find() && matcher.groupCount() > 1) {
099                    if (realmField > 0)
100                        realm = matcher.group(1);
101                    if (timestampField > 0)
102                        at = matcher.group(2);
103                }
104            }
105            if (s.contains("<isomsg")) {
106                inMsg++;
107            }
108            if (s.contains("</isomsg>") && --inMsg == 0) {
109                if (at != null || realm != null && inMsg == 0) {
110                    if (realm != null) {
111                        sb.append("  <field id=\"" + realmField + "\" value=\"" + realm + "\" />");
112                        realm = null;
113                    }
114                    if (at != null) {
115                        sb.append("  <field id=\"" + timestampField + "\" value=\"" + at + "\" />");
116                    }
117                }
118                sb.append (s);
119                break;
120            }
121            if (inMsg > 0)
122                sb.append (s);
123        }
124        return sb.toString().getBytes();
125    }
126    protected int getHeaderLength() { 
127        return 0; 
128    }
129    protected void connect (Socket socket) throws IOException {
130        super.connect (socket);
131        reader = new BufferedReader (new InputStreamReader (serverIn));
132    }
133    public void disconnect () throws IOException {
134        super.disconnect ();
135        reader = null;
136    }
137
138    @Override
139    public void setConfiguration (Configuration cfg) throws ConfigurationException {
140        super.setConfiguration(cfg);
141        timestampField = cfg.getInt("timestamp-field", 0);
142        realmField = cfg.getInt("realm-field", 0);
143    }
144}