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.gui;
020
021import org.jpos.iso.ISOException;
022import org.jpos.iso.ISOMsg;
023import org.jpos.iso.ISOPackager;
024import org.jpos.iso.ISOUtil;
025
026import javax.swing.*;
027import javax.swing.event.ListSelectionEvent;
028import javax.swing.event.ListSelectionListener;
029import javax.swing.table.AbstractTableModel;
030import javax.swing.table.TableModel;
031import java.awt.*;
032import java.util.Vector;
033
034/**
035 * Called from ISOChannelPanel when you click on it's ISOMeter.
036 * It enable field and header visualization by means of visual
037 * components such as JTable
038 *
039 * @see ISOChannelPanel
040 * @see ISORequestListenerPanel
041 */
042@SuppressWarnings({"unchecked", "deprecation"})
043public class ISOMsgPanel extends JPanel {
044
045    private static final long serialVersionUID = 7779880613544725704L;
046    /**
047     * @serial
048     */
049    ISOMsg m;
050    /**
051     * @serial
052     */
053    Vector validFields;
054    public ISOMsgPanel(ISOMsg m, boolean withDump) {
055        super();
056        this.m = m;
057        setLayout(new BorderLayout());
058        setBorder(BorderFactory.createRaisedBevelBorder());
059        setValidFields();
060        add(createISOMsgTable(), BorderLayout.CENTER);
061        if (withDump)
062            add(createISOMsgDumpPanel(), BorderLayout.SOUTH);
063    }
064    public ISOMsgPanel(ISOMsg m) {
065        this(m, false);
066    }
067    private void setValidFields() {
068        validFields = new Vector();
069        for (int i=0; i<=m.getMaxField(); i++)
070            if (m.hasField(i))
071                validFields.addElement(i);
072    }
073    private JComponent createISOMsgTable() {
074        TableModel dataModel = new AbstractTableModel() {
075
076            private static final long serialVersionUID = 8917029825751856951L;
077
078            @Override
079            public int getColumnCount() {
080                return 3;
081            }
082
083            @Override
084            public int getRowCount() {
085                return validFields.size();
086            }
087
088            @Override
089            public String getColumnName(int columnIndex) {
090                switch (columnIndex) {
091                    case 0 :
092                        return "#";
093                    case 1 :
094                        return "Content";
095                    case 2 :
096                        return "Description";
097                    default:
098                        return "";
099                }
100            }
101
102            @Override
103            public Object getValueAt(int row, int col) {
104                switch (col) {
105                    case 0 :
106                        return validFields.elementAt(row);
107                    case 1 :
108                        int index = (Integer) validFields.elementAt(row);
109
110                        Object obj = m.getValue(index);
111                        if (obj instanceof String) {
112                            String s = obj.toString();
113                            switch (index) {
114                                case 2 :
115                                case 35:
116                                case 45:
117                                    s = ISOUtil.protect(s);
118                                    break;
119                                case 14:
120                                    s = "----";
121                            }
122                            return s;
123                        }
124                        else if (obj instanceof byte[])
125                            return ISOUtil.hexString((byte[]) obj);
126                        else if (obj instanceof ISOMsg)
127                            return "<ISOMsg>";
128                        break;
129                    case 2 :
130                        int i = (Integer) validFields.elementAt(row);
131                        ISOPackager p = m.getPackager();
132                        return p.getFieldDescription(m,i);
133                }
134                return "<???>";
135            }
136        };
137        JTable table = new JTable(dataModel);
138        table.getColumnModel().getColumn(0).setPreferredWidth(10);
139        table.setPreferredScrollableViewportSize(
140            new Dimension (500,table.getRowCount()*table.getRowHeight()));
141        table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
142
143        ListSelectionModel rowSM = table.getSelectionModel();
144        rowSM.addListSelectionListener(new ListSelectionListener() {
145            public void valueChanged(ListSelectionEvent e) {
146                if (e.getValueIsAdjusting())
147                    return;
148
149                ListSelectionModel lsm =
150                    (ListSelectionModel)e.getSource();
151                if (!lsm.isSelectionEmpty()) {
152                    int selectedRow = lsm.getMinSelectionIndex();
153                    int index = (Integer)
154                            validFields.elementAt(selectedRow);
155
156                    Object obj = m.getValue(index);
157                    if (obj instanceof ISOMsg) {
158                        ISOMsg sm = (ISOMsg) obj;
159                        JFrame f = new JFrame("ISOMsg field "+index);
160                        ISOMsgPanel p = new ISOMsgPanel(sm, false);
161                        f.getContentPane().add(p);
162                        f.pack();
163                        f.show();
164                    }
165                }
166            }
167        });
168
169        return new JScrollPane(table);
170    }
171    JComponent createISOMsgDumpPanel() {
172        JPanel p = new JPanel();
173        JTextArea t = new JTextArea(3,20);
174
175        p.setLayout(new BorderLayout());
176        p.setBackground(Color.white);
177        p.setBorder(BorderFactory.createLoweredBevelBorder());
178        p.add(new JLabel("Dump", SwingConstants.LEFT),
179            BorderLayout.NORTH);
180        t.setFont(new Font ("Helvetica", Font.PLAIN, 8));
181        t.setLineWrap(true);
182        try {
183            StringBuilder buf = new StringBuilder();
184            if (m.getHeader() != null) {
185                buf.append("--[Header]--\n");
186                buf.append(ISOUtil.hexString(m.getHeader()));
187                buf.append("\n--[Msg]--\n");
188            }
189            byte[] b = m.pack();
190            buf.append (ISOUtil.hexString(b));
191            t.setText(buf.toString());
192        } catch (ISOException e) {
193            t.setText(e.toString());
194            t.setForeground(Color.red);
195        }
196        p.add(t, BorderLayout.CENTER);
197        return p;
198    }
199}