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;
020
021import org.jpos.util.FSDMsg;
022import org.jdom2.JDOMException;
023
024import java.io.*;
025import java.util.Iterator;
026import java.util.Map;
027import java.util.concurrent.locks.Lock;
028import java.util.concurrent.locks.ReentrantLock;
029
030public class FSDISOMsg extends ISOMsg implements Cloneable  {
031    FSDMsg fsd;
032    Lock isLock = new ReentrantLock();
033    public  FSDISOMsg () {
034        super();
035    }
036    public FSDISOMsg (FSDMsg fsd) {
037        super();
038        this.fsd = fsd;
039    }
040    public String getMTI() {
041        return getString(0);
042    }
043    public byte[] pack() throws ISOException {
044        try {
045            return fsd.packToBytes();
046        } catch (Exception e) {
047            throw new ISOException (e);
048        }
049    }
050    public int unpack(byte[] b) throws ISOException {
051        try {
052            fsd.unpack (b);
053            return b.length;
054        } catch (Exception e) {
055            throw new ISOException (e);
056        }
057    }
058    public void unpack (InputStream in) throws IOException, ISOException {
059        isLock.lock();
060        try {
061            fsd.unpack(in);
062        } catch (JDOMException e) {
063            throw new ISOException (e);
064        } finally {
065            isLock.unlock();
066        }
067    }
068
069    public FSDMsg getFSDMsg() {
070        return fsd;
071    }
072    public String getString (int fldno) {
073        return fsd.get (Integer.toString(fldno));
074    }
075    public String getString (String fld) {
076        return fsd.get (fld);
077    }
078    public boolean hasField (int fldno) {
079        return getString(fldno) != null;
080    }
081    public boolean hasField (String fld) {
082        return getString(fld) != null;
083    }
084    public void dump (PrintStream p, String indent) {
085        if (fsd != null)
086            fsd.dump (p, indent);
087    }
088    public void writeExternal (ObjectOutput out) throws IOException {
089        out.writeByte (0);  // reserved for future expansion (version id)
090        out.writeUTF (fsd.getBasePath());
091        out.writeUTF (fsd.getBaseSchema());
092        out.writeObject (fsd.getMap());
093    }
094    public void readExternal  (ObjectInput in) 
095        throws IOException, ClassNotFoundException
096    {
097        in.readByte();  // ignore version for now
098        String basePath = in.readUTF();
099        String baseSchema = in.readUTF();
100        fsd = new FSDMsg (basePath, baseSchema);
101        Map map = (Map) in.readObject();
102        Iterator iter = map.entrySet().iterator();
103        while (iter.hasNext()) {
104            Map.Entry entry = (Map.Entry) iter.next();
105            fsd.set ((String) entry.getKey(), (String) entry.getValue());
106        }
107    }
108    public Object clone() {
109        FSDISOMsg m = (FSDISOMsg) super.clone();
110        m.fsd = (FSDMsg) fsd.clone();
111        return m;
112    }
113    public Object clone(int[] fields) {
114        FSDISOMsg m = (FSDISOMsg) super.clone();
115        m.fsd = new FSDMsg(fsd.getBasePath(), fsd.getBaseSchema());
116        for (int field : fields) {
117            String f = Integer.toString(field);
118            m.fsd.set(f, fsd.get(f));
119        }
120        return m;
121    }
122    public void merge (ISOMsg m) {
123        if (m instanceof FSDISOMsg) {
124            fsd.merge (((FSDISOMsg)m).getFSDMsg());
125        } else {
126            for (int i=0; i<=m.getMaxField(); i++) {
127                if (m.hasField(i))
128                    fsd.set (Integer.toString(i), m.getString(i));
129            }
130        }
131    }
132    public void setResponseMTI() {
133        try {
134            super.setResponseMTI();
135        } catch (ISOException ignored) { }               
136    }
137    public void set (String name, String value) {
138        if (value != null)
139            this.fsd.set (name, value);
140    }   
141    private static final long serialVersionUID = 1L;
142}
143