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.iso.packager.XMLPackager;
022
023import java.io.*;
024
025/**
026 * implements <b>Leaf</b> for standard fields
027 *
028 * @author apr@cs.com.uy
029 * @version $Id$
030 * @see ISOComponent
031 */
032public class ISOField 
033    extends ISOComponent 
034    implements Cloneable, Externalizable
035{
036
037    private static final long serialVersionUID = -4053616930139887829L;
038    protected int fieldNumber;
039    protected String value;
040
041    /**
042     * No args constructor 
043     * <font size="-1">(required by Externalizable support on ISOMsg)</font>
044     */
045    public ISOField () {
046        fieldNumber = -1;
047    }
048
049    /**
050     * @param n - the FieldNumber
051     */
052    public ISOField (int n) {
053        fieldNumber = n;
054    }
055    /**
056     * @param n - fieldNumber
057     * @param v - fieldValue
058     */
059    public ISOField (int n, String v) {
060        fieldNumber = n;
061        value = v;
062    }
063    /**
064     * not available on Leaf - always throw ISOException
065     * @return never returns
066     * @exception ISOException
067     */
068    @Override
069    public byte[] pack() throws ISOException {
070        throw new ISOException ("Not available on Leaf");
071    }
072    /**
073     * not available on Leaf - always throw ISOException
074     * @param b
075     * @return never returns
076     * @exception ISOException
077     */
078    @Override
079    public int unpack(byte[] b) throws ISOException {
080        throw new ISOException ("Not available on Leaf");
081    }
082    /**
083     * not available on Leaf - always throw ISOException
084     * @param in
085     * @exception ISOException
086     */
087    @Override
088    public void unpack(InputStream in) throws ISOException {
089        throw new ISOException ("Not available on Leaf");
090    }
091    /**
092     * @return Object representing this field number
093     */
094    @Override
095    public Object getKey() {
096        return fieldNumber;
097    }
098    /**
099     * @return Object representing this field value
100     */
101    @Override
102    public Object getValue() {
103        return value;
104    }
105    /**
106     * @param obj - Object representing this field value
107     * @exception ISOException
108     */
109    @Override
110    public void setValue(Object obj) throws ISOException {
111        if (obj instanceof String)
112            value = (String) obj;
113        else
114            value = obj.toString();
115    }
116    /**
117     * @return byte[] representing this field
118     */
119    @Override
120    public byte[] getBytes() {
121        return value != null ? value.getBytes(ISOUtil.CHARSET) : new byte[] {};
122    }
123    /**
124     * dump this field to PrintStream. The output is sorta
125     * XML, intended to be easily parsed.
126     * @param p - print stream
127     * @param indent - optional indent string
128     */
129    @Override
130    public void dump (PrintStream p, String indent) {
131        if (value != null) {
132            if (value.indexOf('<') >= 0) {
133                p.print(indent + "<" + XMLPackager.ISOFIELD_TAG + " " +
134                        XMLPackager.ID_ATTR + "=\"" + fieldNumber + "\"><![CDATA[");
135                p.print(value);
136                p.println("]]></" + XMLPackager.ISOFIELD_TAG + ">");
137            } else if (value.startsWith("{")) {
138                p.print(indent + "<" + XMLPackager.ISOFIELD_TAG + " " +
139                        XMLPackager.ID_ATTR + "=\"" + fieldNumber + "\"><![CDATA[");
140                p.print(value);
141                p.println("]]></" + XMLPackager.ISOFIELD_TAG + ">");
142            } else {
143                p.println(indent + "<" + XMLPackager.ISOFIELD_TAG + " " +
144                        XMLPackager.ID_ATTR + "=\"" + fieldNumber + "\" " +
145                        XMLPackager.VALUE_ATTR
146                        + "=\"" + ISOUtil.normalize(value) + "\"/>");
147            }
148        }
149    }
150    /**
151     * changes this Component field number<br>
152     * Use with care, this method does not change
153     * any reference held by a Composite.
154     * @param fieldNumber new field number
155     */
156    @Override
157    public void setFieldNumber (int fieldNumber) {
158        this.fieldNumber = fieldNumber;
159    }
160
161    @Override
162    public int getFieldNumber () {
163        return fieldNumber;
164    }
165    @Override
166    public void writeExternal (ObjectOutput out) throws IOException {
167        out.writeShort (fieldNumber);
168        out.writeUTF (value);
169    }
170    @Override
171    public void readExternal  (ObjectInput in) 
172        throws IOException, ClassNotFoundException
173    {
174        fieldNumber = in.readShort ();
175        value       = in.readUTF();
176    }
177}